summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/fpdfapi/fpdf_render/fpdf_render_text.cpp101
-rw-r--r--core/fxge/ge/fx_ge_text.cpp1208
-rw-r--r--core/fxge/include/fx_font.h8
-rw-r--r--core/fxge/win32/fx_win32_device.cpp12
-rw-r--r--core/fxge/win32/win32_int.h4
5 files changed, 438 insertions, 895 deletions
diff --git a/core/fpdfapi/fpdf_render/fpdf_render_text.cpp b/core/fpdfapi/fpdf_render/fpdf_render_text.cpp
index 225b6726e2..221d04fd70 100644
--- a/core/fpdfapi/fpdf_render/fpdf_render_text.cpp
+++ b/core/fpdfapi/fpdf_render/fpdf_render_text.cpp
@@ -348,13 +348,15 @@ class CPDF_RefType3Cache {
uint32_t m_dwCount;
CPDF_Type3Font* m_pType3Font;
};
+
FX_BOOL CPDF_RenderStatus::ProcessType3Text(const CPDF_TextObject* textobj,
const CFX_Matrix* pObj2Device) {
CPDF_Type3Font* pType3Font = textobj->m_TextState.GetFont()->AsType3Font();
- for (int j = 0; j < m_Type3FontCache.GetSize(); j++) {
- if (m_Type3FontCache.GetAt(j) == pType3Font)
+ for (int i = 0; i < m_Type3FontCache.GetSize(); ++i) {
+ if (m_Type3FontCache.GetAt(i) == pType3Font)
return TRUE;
}
+
CFX_Matrix dCTM = m_pDevice->GetCTM();
FX_FLOAT sa = FXSYS_fabs(dCTM.a);
FX_FLOAT sd = FXSYS_fabs(dCTM.d);
@@ -366,44 +368,43 @@ FX_BOOL CPDF_RenderStatus::ProcessType3Text(const CPDF_TextObject* textobj,
FX_ARGB fill_argb = GetFillArgb(textobj, TRUE);
int fill_alpha = FXARGB_A(fill_argb);
int device_class = m_pDevice->GetDeviceClass();
- FXTEXT_GLYPHPOS* pGlyphAndPos = NULL;
- if (device_class == FXDC_DISPLAY) {
- pGlyphAndPos = FX_Alloc(FXTEXT_GLYPHPOS, textobj->m_nChars);
- } else if (fill_alpha < 255) {
+ std::vector<FXTEXT_GLYPHPOS> glyphs;
+ if (device_class == FXDC_DISPLAY)
+ glyphs.resize(textobj->m_nChars);
+ else if (fill_alpha < 255)
return FALSE;
- }
+
CPDF_RefType3Cache refTypeCache(pType3Font);
uint32_t* pChars = textobj->m_pCharCodes;
- if (textobj->m_nChars == 1) {
+ if (textobj->m_nChars == 1)
pChars = (uint32_t*)(&textobj->m_pCharCodes);
- }
+
for (int iChar = 0; iChar < textobj->m_nChars; iChar++) {
uint32_t charcode = pChars[iChar];
- if (charcode == (uint32_t)-1) {
+ if (charcode == (uint32_t)-1)
continue;
- }
+
CPDF_Type3Char* pType3Char = pType3Font->LoadChar(charcode);
- if (!pType3Char) {
+ if (!pType3Char)
continue;
- }
+
CFX_Matrix matrix = char_matrix;
matrix.e += iChar ? textobj->m_pCharPos[iChar - 1] : 0;
matrix.Concat(text_matrix);
matrix.Concat(*pObj2Device);
if (!pType3Char->LoadBitmap(m_pContext)) {
- if (pGlyphAndPos) {
+ if (!glyphs.empty()) {
for (int i = 0; i < iChar; i++) {
- FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[i];
- if (!glyph.m_pGlyph) {
+ const FXTEXT_GLYPHPOS& glyph = glyphs[i];
+ if (!glyph.m_pGlyph)
continue;
- }
+
m_pDevice->SetBitMask(&glyph.m_pGlyph->m_Bitmap,
glyph.m_OriginX + glyph.m_pGlyph->m_Left,
glyph.m_OriginY - glyph.m_pGlyph->m_Top,
fill_argb);
}
- FX_Free(pGlyphAndPos);
- pGlyphAndPos = NULL;
+ glyphs.clear();
}
CPDF_GraphicStates* pStates = CloneObjStates(textobj, FALSE);
CPDF_RenderOptions Options = m_Options;
@@ -453,18 +454,18 @@ FX_BOOL CPDF_RenderStatus::ProcessType3Text(const CPDF_TextObject* textobj,
CPDF_Type3Cache* pCache = GetCachedType3(pType3Font);
refTypeCache.m_dwCount++;
CFX_GlyphBitmap* pBitmap = pCache->LoadGlyph(charcode, &matrix, sa, sd);
- if (!pBitmap) {
+ if (!pBitmap)
continue;
- }
+
int origin_x = FXSYS_round(matrix.e);
int origin_y = FXSYS_round(matrix.f);
- if (pGlyphAndPos) {
- pGlyphAndPos[iChar].m_pGlyph = pBitmap;
- pGlyphAndPos[iChar].m_OriginX = origin_x;
- pGlyphAndPos[iChar].m_OriginY = origin_y;
- } else {
+ if (glyphs.empty()) {
m_pDevice->SetBitMask(&pBitmap->m_Bitmap, origin_x + pBitmap->m_Left,
origin_y - pBitmap->m_Top, fill_argb);
+ } else {
+ glyphs[iChar].m_pGlyph = pBitmap;
+ glyphs[iChar].m_OriginX = origin_x;
+ glyphs[iChar].m_OriginY = origin_y;
}
} else {
CFX_Matrix image_matrix = pType3Char->m_ImageMatrix;
@@ -479,33 +480,33 @@ FX_BOOL CPDF_RenderStatus::ProcessType3Text(const CPDF_TextObject* textobj,
}
}
}
- if (pGlyphAndPos) {
- FX_RECT rect =
- FXGE_GetGlyphsBBox(pGlyphAndPos, textobj->m_nChars, 0, sa, sd);
- CFX_DIBitmap bitmap;
- if (!bitmap.Create((int)(rect.Width() * sa), (int)(rect.Height() * sd),
- FXDIB_8bppMask)) {
- FX_Free(pGlyphAndPos);
- return TRUE;
- }
- bitmap.Clear(0);
- for (int iChar = 0; iChar < textobj->m_nChars; iChar++) {
- FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[iChar];
- if (!glyph.m_pGlyph) {
- continue;
- }
- bitmap.TransferBitmap(
- (int)((glyph.m_OriginX + glyph.m_pGlyph->m_Left - rect.left) * sa),
- (int)((glyph.m_OriginY - glyph.m_pGlyph->m_Top - rect.top) * sd),
- glyph.m_pGlyph->m_Bitmap.GetWidth(),
- glyph.m_pGlyph->m_Bitmap.GetHeight(), &glyph.m_pGlyph->m_Bitmap, 0,
- 0);
- }
- m_pDevice->SetBitMask(&bitmap, rect.left, rect.top, fill_argb);
- FX_Free(pGlyphAndPos);
+
+ if (glyphs.empty())
+ return TRUE;
+
+ FX_RECT rect = FXGE_GetGlyphsBBox(glyphs, 0, sa, sd);
+ CFX_DIBitmap bitmap;
+ if (!bitmap.Create(static_cast<int>(rect.Width() * sa),
+ static_cast<int>(rect.Height() * sd), FXDIB_8bppMask)) {
+ return TRUE;
}
+ bitmap.Clear(0);
+ for (const FXTEXT_GLYPHPOS& glyph : glyphs) {
+ if (!glyph.m_pGlyph)
+ continue;
+
+ bitmap.TransferBitmap(
+ static_cast<int>(
+ (glyph.m_OriginX + glyph.m_pGlyph->m_Left - rect.left) * sa),
+ static_cast<int>((glyph.m_OriginY - glyph.m_pGlyph->m_Top - rect.top) *
+ sd),
+ glyph.m_pGlyph->m_Bitmap.GetWidth(),
+ glyph.m_pGlyph->m_Bitmap.GetHeight(), &glyph.m_pGlyph->m_Bitmap, 0, 0);
+ }
+ m_pDevice->SetBitMask(&bitmap, rect.left, rect.top, fill_argb);
return TRUE;
}
+
class CPDF_CharPosList {
public:
CPDF_CharPosList();
diff --git a/core/fxge/ge/fx_ge_text.cpp b/core/fxge/ge/fx_ge_text.cpp
index 46edaf7cbe..f2867aaf11 100644
--- a/core/fxge/ge/fx_ge_text.cpp
+++ b/core/fxge/ge/fx_ge_text.cpp
@@ -5,6 +5,7 @@
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
#include <limits>
+#include <vector>
#include "core/fxcodec/include/fx_codec.h"
#include "core/fxge/ge/fx_text_int.h"
@@ -16,11 +17,6 @@
#include "third_party/skia/include/core/SkTypeface.h"
#endif
-#undef FX_GAMMA
-#undef FX_GAMMA_INVERSE
-#define FX_GAMMA(value) (value)
-#define FX_GAMMA_INVERSE(value) (value)
-
namespace {
void ResetTransform(FT_Face face) {
@@ -46,83 +42,33 @@ class ScopedFontTransform {
FT_Face m_Face;
};
-} // namespace
-
-FX_RECT FXGE_GetGlyphsBBox(FXTEXT_GLYPHPOS* pGlyphAndPos,
- int nChars,
- int anti_alias,
- FX_FLOAT retinaScaleX,
- FX_FLOAT retinaScaleY) {
- FX_RECT rect(0, 0, 0, 0);
- FX_BOOL bStarted = FALSE;
- for (int iChar = 0; iChar < nChars; iChar++) {
- FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[iChar];
- const CFX_GlyphBitmap* pGlyph = glyph.m_pGlyph;
- if (!pGlyph) {
- continue;
- }
- int char_left = glyph.m_OriginX + pGlyph->m_Left;
- int char_width = (int)(pGlyph->m_Bitmap.GetWidth() / retinaScaleX);
- if (anti_alias == FXFT_RENDER_MODE_LCD) {
- char_width /= 3;
- }
- int char_right = char_left + char_width;
- int char_top = glyph.m_OriginY - pGlyph->m_Top;
- int char_bottom =
- char_top + (int)(pGlyph->m_Bitmap.GetHeight() / retinaScaleY);
- if (!bStarted) {
- rect.left = char_left;
- rect.right = char_right;
- rect.top = char_top;
- rect.bottom = char_bottom;
- bStarted = TRUE;
- } else {
- if (rect.left > char_left) {
- rect.left = char_left;
- }
- if (rect.right < char_right) {
- rect.right = char_right;
- }
- if (rect.top > char_top) {
- rect.top = char_top;
- }
- if (rect.bottom < char_bottom) {
- rect.bottom = char_bottom;
- }
- }
- }
- return rect;
-}
-static void _AdjustGlyphSpace(FXTEXT_GLYPHPOS* pGlyphAndPos, int nChars) {
- ASSERT(nChars > 1);
- FX_BOOL bVertical = FALSE;
- if (pGlyphAndPos[nChars - 1].m_OriginX == pGlyphAndPos[0].m_OriginX) {
- bVertical = TRUE;
- } else if (pGlyphAndPos[nChars - 1].m_OriginY != pGlyphAndPos[0].m_OriginY) {
+void AdjustGlyphSpace(std::vector<FXTEXT_GLYPHPOS>* pGlyphAndPos) {
+ ASSERT(pGlyphAndPos->size() > 1);
+ std::vector<FXTEXT_GLYPHPOS>& glyphs = *pGlyphAndPos;
+ bool bVertical = glyphs.back().m_OriginX == glyphs.front().m_OriginX;
+ if (!bVertical && (glyphs.back().m_OriginY != glyphs.front().m_OriginY))
return;
- }
- int i = nChars - 1;
- int* next_origin =
- bVertical ? &pGlyphAndPos[i].m_OriginY : &pGlyphAndPos[i].m_OriginX;
- FX_FLOAT next_origin_f =
- bVertical ? pGlyphAndPos[i].m_fOriginY : pGlyphAndPos[i].m_fOriginX;
- for (i--; i > 0; i--) {
- int* this_origin =
- bVertical ? &pGlyphAndPos[i].m_OriginY : &pGlyphAndPos[i].m_OriginX;
- FX_FLOAT this_origin_f =
- bVertical ? pGlyphAndPos[i].m_fOriginY : pGlyphAndPos[i].m_fOriginX;
- int space = (*next_origin) - (*this_origin);
- FX_FLOAT space_f = next_origin_f - this_origin_f;
+
+ for (size_t i = glyphs.size() - 1; i > 1; --i) {
+ FXTEXT_GLYPHPOS& next = glyphs[i];
+ int next_origin = bVertical ? next.m_OriginY : next.m_OriginX;
+ FX_FLOAT next_origin_f = bVertical ? next.m_fOriginY : next.m_fOriginX;
+
+ FXTEXT_GLYPHPOS& current = glyphs[i - 1];
+ int& current_origin = bVertical ? current.m_OriginY : current.m_OriginX;
+ FX_FLOAT current_origin_f =
+ bVertical ? current.m_fOriginY : current.m_fOriginX;
+
+ int space = next_origin - current_origin;
+ FX_FLOAT space_f = next_origin_f - current_origin_f;
FX_FLOAT error =
- (FX_FLOAT)(FXSYS_fabs(space_f) - FXSYS_fabs((FX_FLOAT)(space)));
- if (error > 0.5f) {
- *this_origin += space > 0 ? -1 : 1;
- }
- next_origin = this_origin;
- next_origin_f = this_origin_f;
+ FXSYS_fabs(space_f) - FXSYS_fabs(static_cast<FX_FLOAT>(space));
+ if (error > 0.5f)
+ current_origin += space > 0 ? -1 : 1;
}
}
-static const uint8_t g_TextGammaAdjust[256] = {
+
+const uint8_t g_TextGammaAdjust[256] = {
0, 2, 3, 4, 6, 7, 8, 10, 11, 12, 13, 15, 16, 17, 18,
19, 21, 22, 23, 24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 35,
36, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 51, 52,
@@ -142,12 +88,271 @@ static const uint8_t g_TextGammaAdjust[256] = {
241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 250, 251, 252, 253, 254,
255,
};
-#define ADJUST_ALPHA(background, foreground, src_alpha, text_flags, a) \
- src_alpha = g_TextGammaAdjust[(uint8_t)src_alpha];
-void _Color2Argb(FX_ARGB& argb,
- uint32_t color,
- int alpha_flag,
- void* pIccTransform) {
+
+int TextGammaAdjust(int value) {
+ ASSERT(value >= 0);
+ ASSERT(value <= 255);
+ return g_TextGammaAdjust[value];
+}
+
+int CalcAlpha(int src, int alpha) {
+ return src * alpha / 255;
+}
+
+void Merge(uint8_t src, int channel, int alpha, uint8_t* dest) {
+ *dest = FXDIB_ALPHA_MERGE(*dest, channel, CalcAlpha(src, alpha));
+}
+
+void MergeGammaAdjust(uint8_t src, int channel, int alpha, uint8_t* dest) {
+ *dest =
+ FXDIB_ALPHA_MERGE(*dest, channel, CalcAlpha(TextGammaAdjust(src), alpha));
+}
+
+void MergeGammaAdjustBgr(const uint8_t* src,
+ int r,
+ int g,
+ int b,
+ int a,
+ uint8_t* dest) {
+ MergeGammaAdjust(src[0], b, a, &dest[0]);
+ MergeGammaAdjust(src[1], g, a, &dest[1]);
+ MergeGammaAdjust(src[2], r, a, &dest[2]);
+}
+
+void MergeGammaAdjustRgb(const uint8_t* src,
+ int r,
+ int g,
+ int b,
+ int a,
+ uint8_t* dest) {
+ MergeGammaAdjust(src[2], b, a, &dest[0]);
+ MergeGammaAdjust(src[1], g, a, &dest[1]);
+ MergeGammaAdjust(src[0], r, a, &dest[2]);
+}
+
+int AverageRgb(const uint8_t* src) {
+ return (src[0] + src[1] + src[2]) / 3;
+}
+
+uint8_t CalculateDestAlpha(uint8_t back_alpha, int src_alpha) {
+ return back_alpha + src_alpha - back_alpha * src_alpha / 255;
+}
+
+void ApplyDestAlpha(uint8_t back_alpha,
+ int src_alpha,
+ int r,
+ int g,
+ int b,
+ uint8_t* dest) {
+ uint8_t dest_alpha = CalculateDestAlpha(back_alpha, src_alpha);
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ dest[0] = FXDIB_ALPHA_MERGE(dest[0], b, alpha_ratio);
+ dest[1] = FXDIB_ALPHA_MERGE(dest[1], g, alpha_ratio);
+ dest[2] = FXDIB_ALPHA_MERGE(dest[2], r, alpha_ratio);
+ dest[3] = dest_alpha;
+}
+
+void NormalizeRgbDst(int src_value, int r, int g, int b, int a, uint8_t* dest) {
+ int src_alpha = CalcAlpha(TextGammaAdjust(src_value), a);
+ dest[0] = FXDIB_ALPHA_MERGE(dest[0], b, src_alpha);
+ dest[1] = FXDIB_ALPHA_MERGE(dest[1], g, src_alpha);
+ dest[2] = FXDIB_ALPHA_MERGE(dest[2], r, src_alpha);
+}
+
+void NormalizeRgbSrc(int src_value, int r, int g, int b, int a, uint8_t* dest) {
+ int src_alpha = CalcAlpha(TextGammaAdjust(src_value), a);
+ if (src_alpha == 0)
+ return;
+
+ dest[0] = FXDIB_ALPHA_MERGE(dest[0], b, src_alpha);
+ dest[1] = FXDIB_ALPHA_MERGE(dest[1], g, src_alpha);
+ dest[2] = FXDIB_ALPHA_MERGE(dest[2], r, src_alpha);
+}
+
+void NormalizeArgbDest(int src_value,
+ int r,
+ int g,
+ int b,
+ int a,
+ uint8_t* dest) {
+ int src_alpha = CalcAlpha(TextGammaAdjust(src_value), a);
+ uint8_t back_alpha = dest[3];
+ if (back_alpha == 0) {
+ FXARGB_SETDIB(dest, FXARGB_MAKE(src_alpha, r, g, b));
+ } else if (src_alpha != 0) {
+ ApplyDestAlpha(back_alpha, src_alpha, r, g, b, dest);
+ }
+}
+
+void NormalizeArgbSrc(int src_value,
+ int r,
+ int g,
+ int b,
+ int a,
+ uint8_t* dest) {
+ int src_alpha = CalcAlpha(TextGammaAdjust(src_value), a);
+ if (src_alpha == 0)
+ return;
+
+ uint8_t back_alpha = dest[3];
+ if (back_alpha == 0) {
+ FXARGB_SETDIB(dest, FXARGB_MAKE(src_alpha, r, g, b));
+ } else {
+ ApplyDestAlpha(back_alpha, src_alpha, r, g, b, dest);
+ }
+}
+
+void NextPixel(uint8_t** src_scan, uint8_t** dst_scan, int bpp) {
+ *src_scan += 3;
+ *dst_scan += bpp;
+}
+
+void SetAlpha(uint8_t* alpha) {
+ alpha[3] = 255;
+}
+
+void SetAlphaDoNothing(uint8_t* alpha) {}
+
+void DrawNormalTextHelper(CFX_DIBitmap* bitmap,
+ const CFX_DIBitmap* pGlyph,
+ int nrows,
+ int left,
+ int top,
+ int start_col,
+ int end_col,
+ bool bNormal,
+ bool bBGRStripe,
+ int x_subpixel,
+ int a,
+ int r,
+ int g,
+ int b) {
+ const bool has_alpha = bitmap->GetFormat() == FXDIB_Argb;
+ uint8_t* src_buf = pGlyph->GetBuffer();
+ int src_pitch = pGlyph->GetPitch();
+ uint8_t* dest_buf = bitmap->GetBuffer();
+ int dest_pitch = bitmap->GetPitch();
+ const int Bpp = has_alpha ? 4 : bitmap->GetBPP() / 8;
+ auto* pNormalizeSrcFunc = has_alpha ? &NormalizeArgbSrc : &NormalizeRgbDst;
+ auto* pNormalizeDstFunc = has_alpha ? &NormalizeArgbDest : &NormalizeRgbSrc;
+ auto* pSetAlpha = has_alpha ? &SetAlpha : &SetAlphaDoNothing;
+
+ for (int row = 0; row < nrows; row++) {
+ int dest_row = row + top;
+ if (dest_row < 0 || dest_row >= bitmap->GetHeight())
+ continue;
+
+ uint8_t* src_scan = src_buf + row * src_pitch + (start_col - left) * 3;
+ uint8_t* dest_scan = dest_buf + dest_row * dest_pitch + start_col * Bpp;
+ if (bBGRStripe) {
+ if (x_subpixel == 0) {
+ for (int col = start_col; col < end_col; col++) {
+ if (has_alpha) {
+ Merge(src_scan[2], r, a, &dest_scan[2]);
+ Merge(src_scan[1], g, a, &dest_scan[1]);
+ Merge(src_scan[0], b, a, &dest_scan[0]);
+ } else {
+ MergeGammaAdjustBgr(&src_scan[0], r, g, b, a, &dest_scan[0]);
+ }
+ pSetAlpha(dest_scan);
+ NextPixel(&src_scan, &dest_scan, Bpp);
+ }
+ } else if (x_subpixel == 1) {
+ MergeGammaAdjust(src_scan[1], r, a, &dest_scan[2]);
+ MergeGammaAdjust(src_scan[0], g, a, &dest_scan[1]);
+ if (start_col > left)
+ MergeGammaAdjust(src_scan[-1], b, a, &dest_scan[0]);
+ pSetAlpha(dest_scan);
+ NextPixel(&src_scan, &dest_scan, Bpp);
+ for (int col = start_col + 1; col < end_col - 1; col++) {
+ MergeGammaAdjustBgr(&src_scan[-1], r, g, b, a, &dest_scan[0]);
+ pSetAlpha(dest_scan);
+ NextPixel(&src_scan, &dest_scan, Bpp);
+ }
+ } else {
+ MergeGammaAdjust(src_scan[0], r, a, &dest_scan[2]);
+ if (start_col > left) {
+ MergeGammaAdjust(src_scan[-1], g, a, &dest_scan[1]);
+ MergeGammaAdjust(src_scan[-2], b, a, &dest_scan[0]);
+ }
+ pSetAlpha(dest_scan);
+ NextPixel(&src_scan, &dest_scan, Bpp);
+ for (int col = start_col + 1; col < end_col - 1; col++) {
+ MergeGammaAdjustBgr(&src_scan[-2], r, g, b, a, &dest_scan[0]);
+ pSetAlpha(dest_scan);
+ NextPixel(&src_scan, &dest_scan, Bpp);
+ }
+ }
+ } else {
+ if (x_subpixel == 0) {
+ for (int col = start_col; col < end_col; col++) {
+ if (bNormal) {
+ int src_value = AverageRgb(&src_scan[0]);
+ pNormalizeDstFunc(src_value, r, g, b, a, dest_scan);
+ } else {
+ MergeGammaAdjustRgb(&src_scan[0], r, g, b, a, &dest_scan[0]);
+ pSetAlpha(dest_scan);
+ }
+ NextPixel(&src_scan, &dest_scan, Bpp);
+ }
+ } else if (x_subpixel == 1) {
+ if (bNormal) {
+ int src_value = start_col > left ? AverageRgb(&src_scan[-1])
+ : (src_scan[0] + src_scan[1]) / 3;
+ pNormalizeSrcFunc(src_value, r, g, b, a, dest_scan);
+ } else {
+ if (start_col > left)
+ MergeGammaAdjust(src_scan[-1], r, a, &dest_scan[2]);
+ MergeGammaAdjust(src_scan[0], g, a, &dest_scan[1]);
+ MergeGammaAdjust(src_scan[1], b, a, &dest_scan[0]);
+ pSetAlpha(dest_scan);
+ }
+ NextPixel(&src_scan, &dest_scan, Bpp);
+ for (int col = start_col + 1; col < end_col; col++) {
+ if (bNormal) {
+ int src_value = AverageRgb(&src_scan[-1]);
+ pNormalizeDstFunc(src_value, r, g, b, a, dest_scan);
+ } else {
+ MergeGammaAdjustRgb(&src_scan[-1], r, g, b, a, &dest_scan[0]);
+ pSetAlpha(dest_scan);
+ }
+ NextPixel(&src_scan, &dest_scan, Bpp);
+ }
+ } else {
+ if (bNormal) {
+ int src_value =
+ start_col > left ? AverageRgb(&src_scan[-2]) : src_scan[0] / 3;
+ pNormalizeSrcFunc(src_value, r, g, b, a, dest_scan);
+ } else {
+ if (start_col > left) {
+ MergeGammaAdjust(src_scan[-2], r, a, &dest_scan[2]);
+ MergeGammaAdjust(src_scan[-1], g, a, &dest_scan[1]);
+ }
+ MergeGammaAdjust(src_scan[0], b, a, &dest_scan[0]);
+ pSetAlpha(dest_scan);
+ }
+ NextPixel(&src_scan, &dest_scan, Bpp);
+ for (int col = start_col + 1; col < end_col; col++) {
+ if (bNormal) {
+ int src_value = AverageRgb(&src_scan[-2]);
+ pNormalizeDstFunc(src_value, r, g, b, a, dest_scan);
+ } else {
+ MergeGammaAdjustRgb(&src_scan[-2], r, g, b, a, &dest_scan[0]);
+ pSetAlpha(dest_scan);
+ }
+ NextPixel(&src_scan, &dest_scan, Bpp);
+ }
+ }
+ }
+ }
+}
+
+} // namespace
+
+void Color2Argb(FX_ARGB& argb,
+ uint32_t color,
+ int alpha_flag,
+ void* pIccTransform) {
if (!pIccTransform && !FXGETFLAG_COLORTYPE(alpha_flag)) {
argb = color;
return;
@@ -178,6 +383,43 @@ void _Color2Argb(FX_ARGB& argb,
: FXGETFLAG_ALPHA_STROKE(alpha_flag);
argb = FXARGB_MAKE(bgra[3], bgra[2], bgra[1], bgra[0]);
}
+
+FX_RECT FXGE_GetGlyphsBBox(const std::vector<FXTEXT_GLYPHPOS>& glyphs,
+ int anti_alias,
+ FX_FLOAT retinaScaleX,
+ FX_FLOAT retinaScaleY) {
+ FX_RECT rect(0, 0, 0, 0);
+ bool bStarted = false;
+ for (const FXTEXT_GLYPHPOS& glyph : glyphs) {
+ const CFX_GlyphBitmap* pGlyph = glyph.m_pGlyph;
+ if (!pGlyph)
+ continue;
+
+ int char_left = glyph.m_OriginX + pGlyph->m_Left;
+ int char_width = (int)(pGlyph->m_Bitmap.GetWidth() / retinaScaleX);
+ if (anti_alias == FXFT_RENDER_MODE_LCD) {
+ char_width /= 3;
+ }
+ int char_right = char_left + char_width;
+ int char_top = glyph.m_OriginY - pGlyph->m_Top;
+ int char_bottom =
+ char_top + (int)(pGlyph->m_Bitmap.GetHeight() / retinaScaleY);
+ if (!bStarted) {
+ rect.left = char_left;
+ rect.right = char_right;
+ rect.top = char_top;
+ rect.bottom = char_bottom;
+ bStarted = true;
+ } else {
+ rect.left = std::min(rect.left, char_left);
+ rect.right = std::max(rect.right, char_right);
+ rect.top = std::min(rect.top, char_top);
+ rect.bottom = std::max(rect.bottom, char_bottom);
+ }
+ }
+ return rect;
+}
+
FX_BOOL CFX_RenderDevice::DrawNormalText(int nChars,
const FXTEXT_CHARPOS* pCharPos,
CFX_Font* pFont,
@@ -228,7 +470,8 @@ FX_BOOL CFX_RenderDevice::DrawNormalText(int nChars,
return TRUE;
}
}
- CFX_Matrix char2device, deviceCtm, text2Device;
+ CFX_Matrix char2device;
+ CFX_Matrix text2Device;
if (pText2Device) {
char2device = *pText2Device;
text2Device = *pText2Device;
@@ -247,16 +490,9 @@ FX_BOOL CFX_RenderDevice::DrawNormalText(int nChars,
}
}
int anti_alias = FXFT_RENDER_MODE_MONO;
- FX_BOOL bNormal = FALSE;
+ bool bNormal = false;
if ((text_flags & FXTEXT_NOSMOOTH) == 0) {
if (m_DeviceClass == FXDC_DISPLAY && m_bpp > 1) {
- FX_BOOL bClearType;
- if (!pFont->GetFace() &&
- !(pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_CLEARTYPE)) {
- bClearType = FALSE;
- } else {
- bClearType = text_flags & FXTEXT_CLEARTYPE;
- }
if (!CFX_GEModule::Get()->GetFontMgr()->FTLibrarySupportsHinting()) {
// Some Freetype implementations (like the one packaged with Fedora) do
// not support hinting due to patents 6219025, 6239783, 6307566,
@@ -266,35 +502,36 @@ FX_BOOL CFX_RenderDevice::DrawNormalText(int nChars,
anti_alias = FXFT_RENDER_MODE_NORMAL;
} else if ((m_RenderCaps & (FXRC_ALPHA_OUTPUT | FXRC_CMYK_OUTPUT))) {
anti_alias = FXFT_RENDER_MODE_LCD;
- bNormal = TRUE;
+ bNormal = true;
} else if (m_bpp < 16) {
anti_alias = FXFT_RENDER_MODE_NORMAL;
} else {
- if (bClearType == FALSE) {
- anti_alias = FXFT_RENDER_MODE_LCD;
- bNormal = TRUE;
- } else {
- anti_alias = FXFT_RENDER_MODE_LCD;
+ anti_alias = FXFT_RENDER_MODE_LCD;
+
+ bool bClearType = false;
+ if (pFont->GetFace() ||
+ (pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_CLEARTYPE)) {
+ bClearType = !!(text_flags & FXTEXT_CLEARTYPE);
}
+ bNormal = !bClearType;
}
}
}
- if (!pCache) {
+ if (!pCache)
pCache = CFX_GEModule::Get()->GetFontCache();
- }
+
CFX_FaceCache* pFaceCache = pCache->GetCachedFace(pFont);
FX_FONTCACHE_DEFINE(pCache, pFont);
- FXTEXT_GLYPHPOS* pGlyphAndPos = FX_Alloc(FXTEXT_GLYPHPOS, nChars);
- int iChar;
- deviceCtm = char2device;
+ std::vector<FXTEXT_GLYPHPOS> glyphs(nChars);
CFX_Matrix matrixCTM = GetCTM();
FX_FLOAT scale_x = FXSYS_fabs(matrixCTM.a);
FX_FLOAT scale_y = FXSYS_fabs(matrixCTM.d);
+ CFX_Matrix deviceCtm = char2device;
deviceCtm.Concat(scale_x, 0, 0, scale_y, 0, 0);
text2Device.Concat(scale_x, 0, 0, scale_y, 0, 0);
- for (iChar = 0; iChar < nChars; iChar++) {
- FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[iChar];
- const FXTEXT_CHARPOS& charpos = pCharPos[iChar];
+ for (size_t i = 0; i < glyphs.size(); ++i) {
+ FXTEXT_GLYPHPOS& glyph = glyphs[i];
+ const FXTEXT_CHARPOS& charpos = pCharPos[i];
glyph.m_fOriginX = charpos.m_OriginX;
glyph.m_fOriginY = charpos.m_OriginY;
text2Device.Transform(glyph.m_fOriginX, glyph.m_fOriginY);
@@ -318,10 +555,10 @@ FX_BOOL CFX_RenderDevice::DrawNormalText(int nChars,
charpos.m_FontCharWidth, anti_alias, nativetext_flags);
}
}
- if (anti_alias < FXFT_RENDER_MODE_LCD && nChars > 1) {
- _AdjustGlyphSpace(pGlyphAndPos, nChars);
- }
- FX_RECT bmp_rect1 = FXGE_GetGlyphsBBox(pGlyphAndPos, nChars, anti_alias);
+ if (anti_alias < FXFT_RENDER_MODE_LCD && glyphs.size() > 1)
+ AdjustGlyphSpace(&glyphs);
+
+ FX_RECT bmp_rect1 = FXGE_GetGlyphsBBox(glyphs, anti_alias);
if (scale_x > 1 && scale_y > 1) {
bmp_rect1.left--;
bmp_rect1.top--;
@@ -333,79 +570,64 @@ FX_BOOL CFX_RenderDevice::DrawNormalText(int nChars,
FXSYS_round((FX_FLOAT)bmp_rect1.right / scale_x),
FXSYS_round((FX_FLOAT)bmp_rect1.bottom / scale_y));
bmp_rect.Intersect(m_ClipBox);
- if (bmp_rect.IsEmpty()) {
- FX_Free(pGlyphAndPos);
+ if (bmp_rect.IsEmpty())
return TRUE;
- }
+
int pixel_width = FXSYS_round(bmp_rect.Width() * scale_x);
int pixel_height = FXSYS_round(bmp_rect.Height() * scale_y);
int pixel_left = FXSYS_round(bmp_rect.left * scale_x);
int pixel_top = FXSYS_round(bmp_rect.top * scale_y);
if (anti_alias == FXFT_RENDER_MODE_MONO) {
CFX_DIBitmap bitmap;
- if (!bitmap.Create(pixel_width, pixel_height, FXDIB_1bppMask)) {
- FX_Free(pGlyphAndPos);
+ if (!bitmap.Create(pixel_width, pixel_height, FXDIB_1bppMask))
return FALSE;
- }
+
bitmap.Clear(0);
- for (iChar = 0; iChar < nChars; iChar++) {
- FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[iChar];
- if (!glyph.m_pGlyph) {
+ for (const FXTEXT_GLYPHPOS& glyph : glyphs) {
+ if (!glyph.m_pGlyph)
continue;
- }
+
const CFX_DIBitmap* pGlyph = &glyph.m_pGlyph->m_Bitmap;
bitmap.TransferBitmap(
glyph.m_OriginX + glyph.m_pGlyph->m_Left - pixel_left,
glyph.m_OriginY - glyph.m_pGlyph->m_Top - pixel_top,
pGlyph->GetWidth(), pGlyph->GetHeight(), pGlyph, 0, 0);
}
- FX_Free(pGlyphAndPos);
return SetBitMask(&bitmap, bmp_rect.left, bmp_rect.top, fill_color);
}
CFX_DIBitmap bitmap;
if (m_bpp == 8) {
- if (!bitmap.Create(pixel_width, pixel_height, FXDIB_8bppMask)) {
- FX_Free(pGlyphAndPos);
+ if (!bitmap.Create(pixel_width, pixel_height, FXDIB_8bppMask))
return FALSE;
- }
} else {
- if (!CreateCompatibleBitmap(&bitmap, pixel_width, pixel_height)) {
- FX_Free(pGlyphAndPos);
+ if (!CreateCompatibleBitmap(&bitmap, pixel_width, pixel_height))
return FALSE;
- }
}
+
if (!bitmap.HasAlpha() && !bitmap.IsAlphaMask()) {
bitmap.Clear(0xFFFFFFFF);
- if (!GetDIBits(&bitmap, bmp_rect.left, bmp_rect.top)) {
- FX_Free(pGlyphAndPos);
+ if (!GetDIBits(&bitmap, bmp_rect.left, bmp_rect.top))
return FALSE;
- }
} else {
bitmap.Clear(0);
if (bitmap.m_pAlphaMask) {
bitmap.m_pAlphaMask->Clear(0);
}
}
+
int dest_width = pixel_width;
- uint8_t* dest_buf = bitmap.GetBuffer();
- int dest_pitch = bitmap.GetPitch();
- int Bpp = bitmap.GetBPP() / 8;
int a = 0;
int r = 0;
int g = 0;
int b = 0;
if (anti_alias == FXFT_RENDER_MODE_LCD) {
- _Color2Argb(fill_color, fill_color, alpha_flag | (1 << 24), pIccTransform);
+ Color2Argb(fill_color, fill_color, alpha_flag | (1 << 24), pIccTransform);
ArgbDecode(fill_color, a, r, g, b);
- r = FX_GAMMA(r);
- g = FX_GAMMA(g);
- b = FX_GAMMA(b);
}
- for (iChar = 0; iChar < nChars; iChar++) {
- FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[iChar];
- if (!glyph.m_pGlyph) {
+ for (const FXTEXT_GLYPHPOS& glyph : glyphs) {
+ if (!glyph.m_pGlyph)
continue;
- }
+
const CFX_DIBitmap* pGlyph = &glyph.m_pGlyph->m_Bitmap;
int left = glyph.m_OriginX + glyph.m_pGlyph->m_Left - pixel_left;
int top = glyph.m_OriginY - glyph.m_pGlyph->m_Top - pixel_top;
@@ -413,704 +635,23 @@ FX_BOOL CFX_RenderDevice::DrawNormalText(int nChars,
int nrows = pGlyph->GetHeight();
if (anti_alias == FXFT_RENDER_MODE_NORMAL) {
if (!bitmap.CompositeMask(left, top, ncols, nrows, pGlyph, fill_color, 0,
- 0, FXDIB_BLEND_NORMAL, NULL, FALSE, alpha_flag,
- pIccTransform)) {
- FX_Free(pGlyphAndPos);
+ 0, FXDIB_BLEND_NORMAL, nullptr, FALSE,
+ alpha_flag, pIccTransform)) {
return FALSE;
}
continue;
}
+
bool bBGRStripe = !!(text_flags & FXTEXT_BGR_STRIPE);
ncols /= 3;
int x_subpixel = (int)(glyph.m_fOriginX * 3) % 3;
- uint8_t* src_buf = pGlyph->GetBuffer();
- int src_pitch = pGlyph->GetPitch();
- int start_col = left;
- if (start_col < 0) {
- start_col = 0;
- }
- int end_col = left + ncols;
- if (end_col > dest_width) {
- end_col = dest_width;
- }
- if (start_col >= end_col) {
+ int start_col = std::max(left, 0);
+ int end_col = std::min(left + ncols, dest_width);
+ if (start_col >= end_col)
continue;
- }
- if (bitmap.GetFormat() == FXDIB_Argb) {
- for (int row = 0; row < nrows; row++) {
- int dest_row = row + top;
- if (dest_row < 0 || dest_row >= bitmap.GetHeight()) {
- continue;
- }
- uint8_t* src_scan = src_buf + row * src_pitch + (start_col - left) * 3;
- uint8_t* dest_scan =
- dest_buf + dest_row * dest_pitch + (start_col << 2);
- if (bBGRStripe) {
- if (x_subpixel == 0) {
- for (int col = start_col; col < end_col; col++) {
- int src_alpha = src_scan[2];
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- src_alpha = src_scan[1];
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- src_alpha = src_scan[0];
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- dest_scan[3] = 255;
- dest_scan += 4;
- src_scan += 3;
- }
- } else if (x_subpixel == 1) {
- int src_alpha = src_scan[1];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- if (start_col > left) {
- src_alpha = src_scan[-1];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- }
- dest_scan[3] = 255;
- dest_scan += 4;
- src_scan += 3;
- for (int col = start_col + 1; col < end_col - 1; col++) {
- int src_alpha = src_scan[1];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- src_alpha = src_scan[-1];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- dest_scan[3] = 255;
- dest_scan += 4;
- src_scan += 3;
- }
- } else {
- int src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- if (start_col > left) {
- src_alpha = src_scan[-1];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- src_alpha = src_scan[-2];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- }
- dest_scan[3] = 255;
- dest_scan += 4;
- src_scan += 3;
- for (int col = start_col + 1; col < end_col - 1; col++) {
- int src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- src_alpha = src_scan[-1];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- src_alpha = src_scan[-2];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- dest_scan[3] = 255;
- dest_scan += 4;
- src_scan += 3;
- }
- }
- } else {
- if (x_subpixel == 0) {
- for (int col = start_col; col < end_col; col++) {
- if (bNormal) {
- int src_alpha1 = (src_scan[0] + src_scan[1] + src_scan[2]) / 3;
- ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
- src_alpha1 = src_alpha1 * a / 255;
- uint8_t back_alpha = dest_scan[3];
- if (back_alpha == 0) {
- FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha1, r, g, b));
- dest_scan += 4;
- src_scan += 3;
- continue;
- }
- if (src_alpha1 == 0) {
- dest_scan += 4;
- src_scan += 3;
- continue;
- }
- uint8_t dest_alpha =
- back_alpha + src_alpha1 - back_alpha * src_alpha1 / 255;
- dest_scan[3] = dest_alpha;
- int alpha_ratio = src_alpha1 * 255 / dest_alpha;
- dest_scan[2] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, alpha_ratio));
- dest_scan[1] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, alpha_ratio));
- dest_scan[0] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, alpha_ratio));
- dest_scan += 4;
- src_scan += 3;
- continue;
- }
- int src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- src_alpha = src_scan[1];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- src_alpha = src_scan[2];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- dest_scan[3] = 255;
- dest_scan += 4;
- src_scan += 3;
- }
- } else if (x_subpixel == 1) {
- if (bNormal) {
- int src_alpha1 =
- start_col > left
- ? ((src_scan[-1] + src_scan[0] + src_scan[1]) / 3)
- : ((src_scan[0] + src_scan[1]) / 3);
- ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
- src_alpha1 = src_alpha1 * a / 255;
- if (src_alpha1 == 0) {
- dest_scan += 4;
- src_scan += 3;
- } else {
- uint8_t back_alpha = dest_scan[3];
- if (back_alpha == 0) {
- FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha1, r, g, b));
- } else {
- uint8_t dest_alpha =
- back_alpha + src_alpha1 - back_alpha * src_alpha1 / 255;
- dest_scan[3] = dest_alpha;
- int alpha_ratio = src_alpha1 * 255 / dest_alpha;
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(
- FX_GAMMA(dest_scan[2]), r, alpha_ratio));
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(
- FX_GAMMA(dest_scan[1]), g, alpha_ratio));
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(
- FX_GAMMA(dest_scan[0]), b, alpha_ratio));
- }
- dest_scan += 4;
- src_scan += 3;
- }
- } else {
- if (start_col > left) {
- int src_alpha = src_scan[-1];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- }
- int src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- src_alpha = src_scan[1];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- dest_scan[3] = 255;
- dest_scan += 4;
- src_scan += 3;
- }
- for (int col = start_col + 1; col < end_col; col++) {
- if (bNormal) {
- int src_alpha1 = (src_scan[-1] + src_scan[0] + src_scan[1]) / 3;
- ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
- src_alpha1 = src_alpha1 * a / 255;
- uint8_t back_alpha = dest_scan[3];
- if (back_alpha == 0) {
- FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha1, r, g, b));
- dest_scan += 4;
- src_scan += 3;
- continue;
- }
- if (src_alpha1 == 0) {
- dest_scan += 4;
- src_scan += 3;
- continue;
- }
- uint8_t dest_alpha =
- back_alpha + src_alpha1 - back_alpha * src_alpha1 / 255;
- dest_scan[3] = dest_alpha;
- int alpha_ratio = src_alpha1 * 255 / dest_alpha;
- dest_scan[2] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, alpha_ratio));
- dest_scan[1] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, alpha_ratio));
- dest_scan[0] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, alpha_ratio));
- dest_scan += 4;
- src_scan += 3;
- continue;
- }
- int src_alpha = src_scan[-1];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- src_alpha = src_scan[1];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- dest_scan[3] = 255;
- dest_scan += 4;
- src_scan += 3;
- }
- } else {
- if (bNormal) {
- int src_alpha1 =
- start_col > left
- ? ((src_scan[-2] + src_scan[-1] + src_scan[0]) / 3)
- : ((src_scan[0]) / 3);
- ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
- src_alpha1 = src_alpha1 * a / 255;
- if (src_alpha1 == 0) {
- dest_scan += 4;
- src_scan += 3;
- } else {
- uint8_t back_alpha = dest_scan[3];
- if (back_alpha == 0) {
- FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha1, r, g, b));
- } else {
- uint8_t dest_alpha =
- back_alpha + src_alpha1 - back_alpha * src_alpha1 / 255;
- dest_scan[3] = dest_alpha;
- int alpha_ratio = src_alpha1 * 255 / dest_alpha;
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(
- FX_GAMMA(dest_scan[2]), r, alpha_ratio));
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(
- FX_GAMMA(dest_scan[1]), g, alpha_ratio));
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(
- FX_GAMMA(dest_scan[0]), b, alpha_ratio));
- }
- dest_scan += 4;
- src_scan += 3;
- }
- } else {
- if (start_col > left) {
- int src_alpha = src_scan[-2];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- src_alpha = src_scan[-1];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- }
- int src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- dest_scan[3] = 255;
- dest_scan += 4;
- src_scan += 3;
- }
- for (int col = start_col + 1; col < end_col; col++) {
- if (bNormal) {
- int src_alpha1 =
- (src_scan[-2] + src_scan[-1] + src_scan[0]) / 3;
- ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
- src_alpha1 = src_alpha1 * a / 255;
- uint8_t back_alpha = dest_scan[3];
- if (back_alpha == 0) {
- FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha1, r, g, b));
- dest_scan += 4;
- src_scan += 3;
- continue;
- }
- if (src_alpha1 == 0) {
- dest_scan += 4;
- src_scan += 3;
- continue;
- }
- uint8_t dest_alpha =
- back_alpha + src_alpha1 - back_alpha * src_alpha1 / 255;
- dest_scan[3] = dest_alpha;
- int alpha_ratio = src_alpha1 * 255 / dest_alpha;
- dest_scan[2] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, alpha_ratio));
- dest_scan[1] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, alpha_ratio));
- dest_scan[0] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, alpha_ratio));
- dest_scan += 4;
- src_scan += 3;
- continue;
- }
- int src_alpha = src_scan[-2];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- src_alpha = src_scan[-1];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- dest_scan[3] = 255;
- dest_scan += 4;
- src_scan += 3;
- }
- }
- }
- }
- } else {
- for (int row = 0; row < nrows; row++) {
- int dest_row = row + top;
- if (dest_row < 0 || dest_row >= bitmap.GetHeight()) {
- continue;
- }
- uint8_t* src_scan = src_buf + row * src_pitch + (start_col - left) * 3;
- uint8_t* dest_scan = dest_buf + dest_row * dest_pitch + start_col * Bpp;
- if (bBGRStripe) {
- if (x_subpixel == 0) {
- for (int col = start_col; col < end_col; col++) {
- int src_alpha = src_scan[2];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- src_alpha = src_scan[1];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- dest_scan += Bpp;
- src_scan += 3;
- }
- } else if (x_subpixel == 1) {
- int src_alpha = src_scan[1];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- if (start_col > left) {
- src_alpha = src_scan[-1];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- }
- dest_scan += Bpp;
- src_scan += 3;
- for (int col = start_col + 1; col < end_col - 1; col++) {
- int src_alpha = src_scan[1];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- src_alpha = src_scan[-1];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- dest_scan += Bpp;
- src_scan += 3;
- }
- } else {
- int src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- if (start_col > left) {
- src_alpha = src_scan[-1];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- src_alpha = src_scan[-2];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- }
- dest_scan += Bpp;
- src_scan += 3;
- for (int col = start_col + 1; col < end_col - 1; col++) {
- int src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- src_alpha = src_scan[-1];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- src_alpha = src_scan[-2];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- dest_scan += Bpp;
- src_scan += 3;
- }
- }
- } else {
- if (x_subpixel == 0) {
- for (int col = start_col; col < end_col; col++) {
- if (bNormal) {
- int src_alpha1 = (src_scan[0] + src_scan[1] + src_scan[2]) / 3;
- ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
- src_alpha1 = src_alpha1 * a / 255;
- if (src_alpha1 == 0) {
- dest_scan += Bpp;
- src_scan += 3;
- continue;
- }
- dest_scan[2] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha1));
- dest_scan[1] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha1));
- dest_scan[0] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha1));
- dest_scan += Bpp;
- src_scan += 3;
- continue;
- }
- int src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- src_alpha = src_scan[1];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- src_alpha = src_scan[2];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- dest_scan += Bpp;
- src_scan += 3;
- }
- } else if (x_subpixel == 1) {
- if (bNormal) {
- int src_alpha1 =
- start_col > left
- ? (src_scan[0] + src_scan[1] + src_scan[-1]) / 3
- : (src_scan[0] + src_scan[1]) / 3;
- ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
- src_alpha1 = src_alpha1 * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha1));
- dest_scan[1] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha1));
- dest_scan[0] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha1));
- dest_scan += Bpp;
- src_scan += 3;
- } else {
- if (start_col > left) {
- int src_alpha = src_scan[-1];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- }
- int src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- src_alpha = src_scan[1];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- dest_scan += Bpp;
- src_scan += 3;
- }
- for (int col = start_col + 1; col < end_col; col++) {
- if (bNormal) {
- int src_alpha1 = (src_scan[0] + src_scan[1] + src_scan[-1]) / 3;
- ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
- src_alpha1 = src_alpha1 * a / 255;
- if (src_alpha1 == 0) {
- dest_scan += Bpp;
- src_scan += 3;
- continue;
- }
- dest_scan[2] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha1));
- dest_scan[1] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha1));
- dest_scan[0] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha1));
- dest_scan += Bpp;
- src_scan += 3;
- continue;
- }
- int src_alpha = src_scan[-1];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- src_alpha = src_scan[1];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- dest_scan += Bpp;
- src_scan += 3;
- }
- } else {
- if (bNormal) {
- int src_alpha1 =
- start_col > left
- ? (src_scan[0] + src_scan[-2] + src_scan[-1]) / 3
- : src_scan[0] / 3;
- ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
- src_alpha1 = src_alpha1 * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha1));
- dest_scan[1] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha1));
- dest_scan[0] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha1));
- dest_scan += Bpp;
- src_scan += 3;
- } else {
- if (start_col > left) {
- int src_alpha = src_scan[-2];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- src_alpha = src_scan[-1];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- }
- int src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- dest_scan += Bpp;
- src_scan += 3;
- }
- for (int col = start_col + 1; col < end_col; col++) {
- if (bNormal) {
- int src_alpha1 = ((int)(src_scan[0]) + (int)(src_scan[-2]) +
- (int)(src_scan[-1])) /
- 3;
- ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
- src_alpha1 = src_alpha1 * a / 255;
- if (src_alpha1 == 0) {
- dest_scan += Bpp;
- src_scan += 3;
- continue;
- }
- dest_scan[2] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha1));
- dest_scan[1] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha1));
- dest_scan[0] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha1));
- dest_scan += Bpp;
- src_scan += 3;
- continue;
- }
- int src_alpha = src_scan[-2];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- src_alpha = src_scan[-1];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(
- FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- dest_scan += Bpp;
- src_scan += 3;
- }
- }
- }
- }
- }
+
+ DrawNormalTextHelper(&bitmap, pGlyph, nrows, left, top, start_col, end_col,
+ bNormal, bBGRStripe, x_subpixel, a, r, g, b);
}
if (bitmap.IsAlphaMask()) {
SetBitMask(&bitmap, bmp_rect.left, bmp_rect.top, fill_color, alpha_flag,
@@ -1118,9 +659,10 @@ FX_BOOL CFX_RenderDevice::DrawNormalText(int nChars,
} else {
SetDIBits(&bitmap, bmp_rect.left, bmp_rect.top);
}
- FX_Free(pGlyphAndPos);
+
return TRUE;
}
+
FX_BOOL CFX_RenderDevice::DrawTextPath(int nChars,
const FXTEXT_CHARPOS* pCharPos,
CFX_Font* pFont,
diff --git a/core/fxge/include/fx_font.h b/core/fxge/include/fx_font.h
index 6bc9b2e4c2..762cdfaf87 100644
--- a/core/fxge/include/fx_font.h
+++ b/core/fxge/include/fx_font.h
@@ -528,8 +528,12 @@ struct FXTEXT_GLYPHPOS {
FX_FLOAT m_fOriginY;
};
-FX_RECT FXGE_GetGlyphsBBox(FXTEXT_GLYPHPOS* pGlyphAndPos,
- int nChars,
+void Color2Argb(FX_ARGB& argb,
+ uint32_t color,
+ int alpha_flag,
+ void* pIccTransform);
+
+FX_RECT FXGE_GetGlyphsBBox(const std::vector<FXTEXT_GLYPHPOS>& glyphs,
int anti_alias,
FX_FLOAT retinaScaleX = 1.0f,
FX_FLOAT retinaScaleY = 1.0f);
diff --git a/core/fxge/win32/fx_win32_device.cpp b/core/fxge/win32/fx_win32_device.cpp
index f8057e7d5d..3d96deb9e4 100644
--- a/core/fxge/win32/fx_win32_device.cpp
+++ b/core/fxge/win32/fx_win32_device.cpp
@@ -13,6 +13,7 @@
#include "core/fxge/agg/fx_agg_driver.h"
#include "core/fxge/dib/dib_int.h"
#include "core/fxge/ge/fx_text_int.h"
+#include "core/fxge/include/fx_font.h"
#include "core/fxge/include/fx_freetype.h"
#include "core/fxge/include/fx_ge_win32.h"
#include "core/fxge/win32/dwrite_int.h"
@@ -627,8 +628,7 @@ FX_BOOL CGdiDeviceDriver::GDI_StretchBitMask(const CFX_DIBitmap* pBitmap1,
if (!pBitmap || dest_width == 0 || dest_height == 0) {
return FALSE;
}
- _Color2Argb(bitmap_color, bitmap_color, alpha_flag | (1 << 24),
- pIccTransform);
+ Color2Argb(bitmap_color, bitmap_color, alpha_flag | (1 << 24), pIccTransform);
int width = pBitmap->GetWidth(), height = pBitmap->GetHeight();
struct {
BITMAPINFOHEADER bmiHeader;
@@ -855,8 +855,8 @@ FX_BOOL CGdiDeviceDriver::DrawPath(const CFX_PathData* pPathData,
if (blend_type != FXDIB_BLEND_NORMAL) {
return FALSE;
}
- _Color2Argb(fill_color, fill_color, alpha_flag | (1 << 24), pIccTransform);
- _Color2Argb(stroke_color, stroke_color, alpha_flag, pIccTransform);
+ Color2Argb(fill_color, fill_color, alpha_flag | (1 << 24), pIccTransform);
+ Color2Argb(stroke_color, stroke_color, alpha_flag, pIccTransform);
CWin32Platform* pPlatform =
(CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
if (!(pGraphState || stroke_color == 0) &&
@@ -963,7 +963,7 @@ FX_BOOL CGdiDeviceDriver::FillRect(const FX_RECT* pRect,
if (blend_type != FXDIB_BLEND_NORMAL) {
return FALSE;
}
- _Color2Argb(fill_color, fill_color, alpha_flag | (1 << 24), pIccTransform);
+ Color2Argb(fill_color, fill_color, alpha_flag | (1 << 24), pIccTransform);
int alpha;
FX_COLORREF rgb;
ArgbDecode(fill_color, alpha, rgb);
@@ -1019,7 +1019,7 @@ FX_BOOL CGdiDeviceDriver::DrawCosmeticLine(FX_FLOAT x1,
if (blend_type != FXDIB_BLEND_NORMAL) {
return FALSE;
}
- _Color2Argb(color, color, alpha_flag | (1 << 24), pIccTransform);
+ Color2Argb(color, color, alpha_flag | (1 << 24), pIccTransform);
int a;
FX_COLORREF rgb;
ArgbDecode(color, a, rgb);
diff --git a/core/fxge/win32/win32_int.h b/core/fxge/win32/win32_int.h
index 7916690817..619ac2fdae 100644
--- a/core/fxge/win32/win32_int.h
+++ b/core/fxge/win32/win32_int.h
@@ -361,9 +361,5 @@ class CPSPrinterDriver : public IFX_RenderDeviceDriver {
CPSOutput* m_pPSOutput;
CFX_PSRenderer m_PSRenderer;
};
-void _Color2Argb(FX_ARGB& argb,
- uint32_t color,
- int alpha_flag,
- void* pIccTransform);
#endif // CORE_FXGE_WIN32_WIN32_INT_H_