static bool get_packed_glyph_image(SkGlyphCache* cache, const SkGlyph& glyph, int width, int height, int dstRB, GrMaskFormat expectedMaskFormat, void* dst) { SkASSERT(glyph.fWidth == width); SkASSERT(glyph.fHeight == height); const void* src = cache->findImage(glyph); if (nullptr == src) { return false; } // crbug:510931 // Retrieving the image from the cache can actually change the mask format. This case is very // uncommon so for now we just draw a clear box for these glyphs. if (get_packed_glyph_mask_format(glyph) != expectedMaskFormat) { const int bpp = GrMaskFormatBytesPerPixel(expectedMaskFormat); for (int y = 0; y < height; y++) { sk_bzero(dst, width * bpp); dst = (char*)dst + dstRB; } return true; } int srcRB = glyph.rowBytes(); // The windows font host sometimes has BW glyphs in a non-BW strike. So it is important here to // check the glyph's format, not the strike's format, and to be able to convert to any of the // GrMaskFormats. if (SkMask::kBW_Format == glyph.fMaskFormat) { // expand bits to our mask type const uint8_t* bits = reinterpret_cast<const uint8_t*>(src); switch (expectedMaskFormat) { case kA8_GrMaskFormat:{ uint8_t* bytes = reinterpret_cast<uint8_t*>(dst); expand_bits(bytes, bits, width, height, dstRB, srcRB); break; } case kA565_GrMaskFormat: { uint16_t* rgb565 = reinterpret_cast<uint16_t*>(dst); expand_bits(rgb565, bits, width, height, dstRB, srcRB); break; } default: SkFAIL("Invalid GrMaskFormat"); } } else if (srcRB == dstRB) { memcpy(dst, src, dstRB * height); } else { const int bbp = GrMaskFormatBytesPerPixel(expectedMaskFormat); for (int y = 0; y < height; y++) { memcpy(dst, src, width * bbp); src = (const char*)src + srcRB; dst = (char*)dst + dstRB; } } return true; }
bool SkGrFontScaler::getPackedGlyphImage(GrGlyph::PackedID packed, int width, int height, int dstRB, void* dst) { const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed), GrGlyph::UnpackFixedX(packed), GrGlyph::UnpackFixedY(packed)); SkASSERT(glyph.fWidth == width); SkASSERT(glyph.fHeight == height); const void* src = fStrike->findImage(glyph); if (NULL == src) { return false; } int srcRB = glyph.rowBytes(); // The windows font host sometimes has BW glyphs in a non-BW strike. So it is important here to // check the glyph's format, not the strike's format, and to be able to convert to any of the // GrMaskFormats. if (SkMask::kBW_Format == glyph.fMaskFormat) { // expand bits to our mask type const uint8_t* bits = reinterpret_cast<const uint8_t*>(src); switch (this->getMaskFormat()) { case kA8_GrMaskFormat: { uint8_t* bytes = reinterpret_cast<uint8_t*>(dst); expand_bits(bytes, bits, width, height, dstRB, srcRB); break; } case kA565_GrMaskFormat: { uint16_t* rgb565 = reinterpret_cast<uint16_t*>(dst); expand_bits(rgb565, bits, width, height, dstRB, srcRB); break; } case kA888_GrMaskFormat: { uint32_t* rgba8888 = reinterpret_cast<uint32_t*>(dst); expand_bits(rgba8888, bits, width, height, dstRB, srcRB); break; } default: GrCrash("Invalid GrMaskFormat"); } } else if (srcRB == dstRB) { memcpy(dst, src, dstRB * height); } else { const int bbp = GrMaskFormatBytesPerPixel(this->getMaskFormat()); for (int y = 0; y < height; y++) { memcpy(dst, src, width * bbp); src = (const char*)src + srcRB; dst = (char*)dst + dstRB; } } return true; }
static int get_section ( BITS *bits, /* Bitstring to work with */ int index, /* Index block number */ int section, /* Section within index */ byte *buffer, /* Returned buffer */ Bool update) /* If TRUE, frees section blocks */ { BITBLOCK *index_block, /* Points to index block */ *section_block; /* Points to section block */ dbyte section_head, /* Section block list head */ block_nbr, /* Entry into block table */ block_next; /* Next block in section list */ static byte comp [BIT_SECTSIZE + 1]; /* Section blocks' data */ word comp_size, /* Size of compressed data */ expand_size; /* Size of expanded data */ ASSERT (bits); ASSERT (buffer); index_block = bits-> block [index]; section_head = index_block-> block.index [section]; if (section_head == 0x0000) /* All 0's */ memset (buffer, 0x00, BIT_SECTSIZE); else if (section_head == 0xFFFF) /* All 1's */ memset (buffer, 0xFF, BIT_SECTSIZE); else { block_nbr = section_head; comp_size = 0; /* Get compressed block */ while (block_nbr) /* from 1 or more sections */ { section_block = bits-> block [block_nbr]; ASSERT (comp_size < BIT_SECTSIZE); memcpy (comp + comp_size, section_block-> block.data, section_block-> size); comp_size += section_block-> size; block_next = section_block-> right; if (update) { /* Move block to free list */ section_block-> right = bits-> free_list; section_block-> size = 0; bits-> free_list = block_nbr; } block_nbr = block_next; } if (update) /* Wipe section block list */ index_block-> block.index [section] = 0; expand_size = expand_bits (comp, buffer, comp_size); ASSERT (expand_size == BIT_SECTSIZE); } return 0; }
local expand_file_rle (FILE *input, FILE *output) { word in_size, out_size; while ((fread (&in_size, 1, sizeof (in_size), input)) > 0) { ASSERT (fread (in_block, 1, in_size, input)); out_size = expand_bits (in_block, out_block, in_size); ASSERT (fwrite (out_block, 1, out_size, output)); printf ("rle expand: in=%d out=%d\n", in_size, out_size); } }