CAImage* CAEmojiFont::getEmojiImage(unsigned int codepoint, unsigned long nFontSize) { int best_match = 0; int diff = std::abs((int)(nFontSize - m_CurFontFace->available_sizes[0].width)); for (int i = 1; i < m_CurFontFace->num_fixed_sizes; ++i) { int ndiff = std::abs((int)(nFontSize - m_CurFontFace->available_sizes[i].width)); if (ndiff < diff) { best_match = i; diff = ndiff; } } FT_Select_Size(m_CurFontFace, best_match); uint32_t glyph_index = FT_Get_Char_Index(m_CurFontFace, codepoint); if (glyph_index == 0) return NULL; FT_Error error = FT_Load_Glyph(m_CurFontFace, glyph_index, FT_LOAD_COLOR); if (error) return NULL; error = FT_Render_Glyph(m_CurFontFace->glyph, FT_RENDER_MODE_NORMAL); if (error) return NULL; int w = (m_CurFontFace->glyph->advance.x >> 6); int h = static_cast<uint32_t>(m_CurFontFace->glyph->metrics.height >> 6); int size = w * h * 4; std::vector<uint8_t> bitmap; bitmap.resize(size); bitmap.assign(size, 0x00); FT_GlyphSlot slot = m_CurFontFace->glyph; uint8_t* src = slot->bitmap.buffer; // FIXME: Should use metrics for drawing. (e.g. calculate baseline) int yoffset = h - slot->bitmap.rows; for (int y = 0; y < slot->bitmap.rows; ++y) { uint8_t* dest = &bitmap[((y + yoffset) * w) * 4]; for (int x = 0; x < slot->bitmap.width; ++x) { uint8_t b = *src++, g = *src++, r = *src++, a = *src++; *dest++ = r; *dest++ = g; *dest++ = b; *dest++ = a; } } CAImage* image = new CAImage(); if (!image->initWithRawData(&bitmap[0], CAImage::PixelFormat_RGBA8888, w, h)) { delete image; return NULL; } image->autorelease(); return image; }
CAImageView* CAWebViewImpl::getWebViewImage() { getWebViewImageJNI(_viewTag); if (!s_cszWebViewImageData.empty()) { DSize size = _webView->getBounds().size; CAImage* pImage = new CAImage(); if (!pImage->initWithRawData((const unsigned char*)&s_cszWebViewImageData[0], CAImage::PixelFormat_RGBA8888, size.width, size.height)) { delete pImage; return NULL; } pImage->autorelease(); return CAImageView::createWithImage(pImage); } return NULL; }