Unverified Commit c1ebeed9 authored by Hong Minhee's avatar Hong Minhee
Browse files

Merge pull request #308 from dodok8/dodok8-fix-issue-304

parents 99af9e62 3b0f51b6
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -78,7 +78,7 @@ To be released.

  -  Fixed a bug where the `fedify node` command had failed to correctly
     render the favicon in terminal emulators that do not support 24-bit
     colors.  [[#168], [#282] by Hyeonseo Kim]
     colors.  [[#168], [#282], [#304] by Hyeonseo Kim]

[#168]: https://github.com/fedify-dev/fedify/issues/168
[#248]: https://github.com/fedify-dev/fedify/issues/248
@@ -91,6 +91,7 @@ To be released.
[#285]: https://github.com/fedify-dev/fedify/pull/285
[#298]: https://github.com/fedify-dev/fedify/pull/298
[#300]: https://github.com/fedify-dev/fedify/pull/300
[#304]: https://github.com/fedify-dev/fedify/issues/304


Version 1.7.5
+54 −14
Original line number Diff line number Diff line
@@ -152,30 +152,70 @@ Deno.test("rgbTo256Color - check grayscale", () => {
  assertEquals(results, expected_gray_idx);
});

Deno.test("getAsciiArt - Darkest Letter", async () => {
  // Create black and white 1x1 images using Jimp constructor
  const blackImage = new Jimp({ width: 1, height: 1, color: 0x000000ff });
  const blackImageBuffer = await blackImage.getBuffer("image/webp");
async function createTestImage(
  color: number,
): Promise<Awaited<ReturnType<typeof Jimp.read>>> {
  const image = new Jimp({ width: 1, height: 1, color });
  const imageBuffer = await image.getBuffer("image/webp");
  return Jimp.read(imageBuffer);
}

Deno.test("getAsciiArt - Darkest Letter without color support", async () => {
  const blackResult = getAsciiArt(
    await Jimp.read(blackImageBuffer),
    await createTestImage(0x000000ff),
    1,
    true,
    "none",
  );

  assertEquals(blackResult, "");
});

Deno.test("getAsciiArt - Brightest Letter", async () => {
  // Create black and white 1x1 images using Jimp constructor
  const whiteImage = new Jimp({ width: 1, height: 1, color: 0xffffffff });
  const whiteImageBuffer = await whiteImage.getBuffer("image/webp");

Deno.test("getAsciiArt - Brightest Letter without color support", async () => {
  const whiteResult = getAsciiArt(
    await Jimp.read(whiteImageBuffer),
    await createTestImage(0xffffffff),
    1,
    true,
    "none",
  );

  assertEquals(whiteResult, " ");
});

Deno.test("getAsciiArt - Darkest Letter with 256 color support", async () => {
  const blackResult = getAsciiArt(
    await createTestImage(0x000000ff),
    1,
    "256color",
  );

  assertEquals(blackResult, "\u001b[38;5;16m█\u001b[39m");
});

Deno.test("getAsciiArt - Brightest Letter with 256 color support", async () => {
  const whiteResult = getAsciiArt(
    await createTestImage(0xffffffff),
    1,
    "256color",
  );

  assertEquals(whiteResult, "\u001b[38;5;231m \u001b[39m");
});

Deno.test("getAsciiArt - Darkest Letter with true color support", async () => {
  const blackResult = getAsciiArt(
    await createTestImage(0x000000ff),
    1,
    "truecolor",
  );

  assertEquals(blackResult, "\u001b[38;2;0;0;0m█\u001b[39m");
});

Deno.test("getAsciiArt - Brightest Letter with true color support", async () => {
  const whiteResult = getAsciiArt(
    await createTestImage(0xffffffff),
    1,
    "truecolor",
  );

  assertEquals(whiteResult, "\u001b[38;2;255;255;255m \u001b[39m");
});
+36 −10
Original line number Diff line number Diff line
@@ -98,8 +98,8 @@ export const command = new Command()
            buffer = images[0].buffer;
          }
          const image = await Jimp.read(buffer);
          const trueColorSupport = checkTerminalTrueColorSupport();
          layout = getAsciiArt(image, DEFAULT_IMAGE_WIDTH, trueColorSupport)
          const colorSupport = checkTerminalColorSupport();
          layout = getAsciiArt(image, DEFAULT_IMAGE_WIDTH, colorSupport)
            .split("\n").map((line) => ` ${line}  `);
          defaultWidth = 41;
        } else {
@@ -258,16 +258,40 @@ export const Jimp = createJimp({
  plugins: defaultPlugins,
});

function checkTerminalTrueColorSupport() {
function checkTerminalColorSupport(): "truecolor" | "256color" | "none" {
  // Check if colors are explicitly disabled
  const noColor = Deno.env.get("NO_COLOR");
  if (noColor != null && noColor !== "") {
    return "none";
  }

  // Check for true color (24-bit) support
  const colorTerm = Deno.env.get("COLORTERM");
  if (
    colorTerm != null &&
    (colorTerm.includes("24bit") || colorTerm.includes("truecolor"))
  ) {
    return "truecolor";
  }

  // Check for xterm 256-color support
  const term = Deno.env.get("TERM");
  if (
    colorTerm == null ||
    !(colorTerm.includes("24bit") || colorTerm.includes("truecolor"))
    term != null &&
    (term.includes("256color") ||
      term.includes("xterm") ||
      term === "screen" ||
      term === "tmux")
  ) {
    return false;
    return "256color";
  }
  return true;

  // Fallback: assume basic color support if TERM is set
  if (term != null && term !== "dumb") {
    return "256color";
  }

  return "none";
}

const DEFAULT_IMAGE_WIDTH = 38;
@@ -326,7 +350,7 @@ export function rgbTo256Color(r: number, g: number, b: number): number {
export function getAsciiArt(
  image: Awaited<ReturnType<typeof Jimp.read>>,
  width = DEFAULT_IMAGE_WIDTH,
  trueColorSupport: boolean,
  colorSupport: "truecolor" | "256color" | "none",
): string {
  const ratio = image.width / image.height;
  const height = Math.round(
@@ -348,11 +372,13 @@ export function getAsciiArt(
      );
      const char = ASCII_CHARS[charIndex];

      if (trueColorSupport) {
      if (colorSupport === "truecolor") {
        art += colors.rgb24(char, color);
      } else {
      } else if (colorSupport === "256color") {
        const colorIndex = rgbTo256Color(color.r, color.g, color.b);
        art += colors.rgb8(char, colorIndex);
      } else {
        art += char;
      }
    }
    if (y < height - 1) art += "\n";