string count_trace (font fn, array<int> cs) { array<int> a; for (int i= 0; i < N(cs); i++) { string s; s << ((char) cs[i]); glyph g= fn->get_glyph (s); if (is_nil (g)) return ""; a << pixel_count (g); } return array_trace (a); }
static void bitmap_alpha_to_a8(const SkBitmap& bitmap, SkWStream* out) { if (!bitmap.getPixels()) { fill_stream(out, '\xFF', pixel_count(bitmap)); return; } SkBitmap copy; const SkBitmap& bm = not4444(bitmap, ©); SkAutoLockPixels autoLockPixels(bm); SkColorType colorType = bm.colorType(); switch (colorType) { case kRGBA_8888_SkColorType: case kBGRA_8888_SkColorType: { SkAutoTMalloc<uint8_t> scanline(bm.width()); for (int y = 0; y < bm.height(); ++y) { uint8_t* dst = scanline.get(); const SkPMColor* src = bm.getAddr32(0, y); for (int x = 0; x < bm.width(); ++x) { *dst++ = SkGetA32Component(*src++, colorType); } out->write(scanline.get(), bm.width()); } return; } case kAlpha_8_SkColorType: for (int y = 0; y < bm.height(); ++y) { out->write(bm.getAddr8(0, y), bm.width()); } return; case kIndex_8_SkColorType: { SkColorTable* ct = bm.getColorTable(); SkASSERT(ct); SkAutoTMalloc<uint8_t> scanline(bm.width()); for (int y = 0; y < bm.height(); ++y) { uint8_t* dst = scanline.get(); const uint8_t* src = bm.getAddr8(0, y); for (int x = 0; x < bm.width(); ++x) { *dst++ = SkGetPackedA32((*ct)[*src++]); } out->write(scanline.get(), bm.width()); } return; } case kRGB_565_SkColorType: case kGray_8_SkColorType: SkDEBUGFAIL("color type has no alpha"); return; case kARGB_4444_SkColorType: SkDEBUGFAIL("4444 color type should have been converted to N32"); return; case kUnknown_SkColorType: default: SkDEBUGFAIL("unexpected color type"); } }
void analyze_major (font fn, font_metric fnm, array<string>& r) { if (range_exists (fnm, 0x41, 0x5a) && range_exists (fnm, 0x61, 0x7a)) { metric_struct* x= fnm->get (0x78); int ex= max (x->y2 / 256, 1); r << (string ("ex=") * as_string (ex)); metric_struct* M= fnm->get (0x4d); int em_rat= (100 * (M->x2 / 256)) / ex; r << (string ("em=") * as_string (em_rat)); glyph glo= fn->get_glyph ("o"); if (!is_nil (glo)) { int lvw= (100 * vertical_stroke_width (glo)) / ex; int lhw= (100 * horizontal_stroke_width (glo)) / ex; r << (string ("lvw=") * as_string (lvw)); r << (string ("lhw=") * as_string (lhw)); } glyph glO= fn->get_glyph ("O"); if (!is_nil (glO)) { int uvw= (100 * vertical_stroke_width (glO)) / ex; int uhw= (100 * horizontal_stroke_width (glO)) / ex; r << (string ("uvw=") * as_string (uvw)); r << (string ("uhw=") * as_string (uhw)); } int cnt= 0; int totlw= 0; double fill= 0.0; for (int i= 0x41; i<=0x7a; i++) if (i <= 0x5a || i >= 0x61) { string s; s << ((char) i); glyph g= fn->get_glyph (s); if (!is_nil (g)) { cnt += pixel_count (g); totlw += g->lwidth; fill += fill_rate (g); } } int fillp= (int) (100.0 * (fill / 52.0)); int vcnt= cnt / max (totlw, 1); r << (string ("fillp=") * as_string (fillp)); r << (string ("vcnt=") * as_string (vcnt)); int lo_lw= 0; int lo_pw= 0; for (int i= 0x61; i<=0x7a; i++) { metric_struct* c= fnm->get (i); lo_lw += (c->x2 / 256); string s; s << ((char) i); glyph g= fn->get_glyph (s); if (!is_nil (g)) lo_pw += g->width; } int lasprat= (100 * lo_lw) / (26 * ex); int pasprat= (100 * lo_pw) / (26 * ex); r << (string ("lasprat=") * as_string (lasprat)); r << (string ("pasprat=") * as_string (pasprat)); //int irreg= irregularity (fnm); //r << (string ("irreg=") * as_string (irreg)); int loasc= (100 * max_ascent (fnm, 0x61, 0x7a)) / ex; int lodes= (100 * (ex + max_descent (fnm, 0x61, 0x7a))) / ex; r << (string ("loasc=") * as_string (loasc)); r << (string ("lodes=") * as_string (lodes)); if (range_exists (fnm, 0x30, 0x39)) { int dides= (100 * (ex + max_descent (fnm, 0x30, 0x39))) / ex; r << (string ("dides=") * as_string (dides)); } } }
static void bitmap_to_pdf_pixels(const SkBitmap& bitmap, SkWStream* out) { if (!bitmap.getPixels()) { size_t size = pixel_count(bitmap) * pdf_color_component_count(bitmap.colorType()); fill_stream(out, '\x00', size); return; } SkBitmap copy; const SkBitmap& bm = not4444(bitmap, ©); SkAutoLockPixels autoLockPixels(bm); SkColorType colorType = bm.colorType(); switch (colorType) { case kRGBA_8888_SkColorType: case kBGRA_8888_SkColorType: { SkASSERT(3 == pdf_color_component_count(colorType)); SkAutoTMalloc<uint8_t> scanline(3 * bm.width()); for (int y = 0; y < bm.height(); ++y) { const uint32_t* src = bm.getAddr32(0, y); uint8_t* dst = scanline.get(); for (int x = 0; x < bm.width(); ++x) { uint32_t color = *src++; U8CPU alpha = SkGetA32Component(color, colorType); if (alpha != SK_AlphaTRANSPARENT) { pmcolor_to_rgb24(color, dst, colorType); } else { get_neighbor_avg_color(bm, x, y, dst, colorType); } dst += 3; } out->write(scanline.get(), 3 * bm.width()); } return; } case kRGB_565_SkColorType: { SkASSERT(3 == pdf_color_component_count(colorType)); SkAutoTMalloc<uint8_t> scanline(3 * bm.width()); for (int y = 0; y < bm.height(); ++y) { const uint16_t* src = bm.getAddr16(0, y); uint8_t* dst = scanline.get(); for (int x = 0; x < bm.width(); ++x) { U16CPU color565 = *src++; *dst++ = SkPacked16ToR32(color565); *dst++ = SkPacked16ToG32(color565); *dst++ = SkPacked16ToB32(color565); } out->write(scanline.get(), 3 * bm.width()); } return; } case kAlpha_8_SkColorType: SkASSERT(1 == pdf_color_component_count(colorType)); fill_stream(out, '\x00', pixel_count(bm)); return; case kGray_8_SkColorType: case kIndex_8_SkColorType: SkASSERT(1 == pdf_color_component_count(colorType)); // these two formats need no transformation to serialize. for (int y = 0; y < bm.height(); ++y) { out->write(bm.getAddr8(0, y), bm.width()); } return; case kUnknown_SkColorType: case kARGB_4444_SkColorType: default: SkDEBUGFAIL("unexpected color type"); } }