From b048f791a15f2da781a01eba5b09eb9d389f9c11 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Tue, 4 Aug 2015 12:19:10 -0700 Subject: clang-format all pdfium code. No behavior change. Generated by: find . -name '*.cpp' -o -name '*.h' | \ grep -E -v 'third_party|thirdparties|lpng_v163' | \ xargs ../../buildtools/mac/clang-format -i See thread "tabs vs spaces" on pdfium@googlegroups.com for discussion. BUG=none R=tsepez@chromium.org Review URL: https://codereview.chromium.org/1265503005 . --- core/src/fxge/agg/include/fx_agg_driver.h | 245 +- core/src/fxge/agg/src/fx_agg_driver.cpp | 3149 +++++----- core/src/fxge/android/fpf_skiafont.cpp | 378 +- core/src/fxge/android/fpf_skiafont.h | 84 +- core/src/fxge/android/fpf_skiafontmgr.cpp | 915 ++- core/src/fxge/android/fpf_skiafontmgr.h | 182 +- core/src/fxge/android/fpf_skiamodule.cpp | 42 +- core/src/fxge/android/fpf_skiamodule.h | 18 +- core/src/fxge/android/fx_android_font.cpp | 131 +- core/src/fxge/android/fx_android_font.h | 51 +- core/src/fxge/android/fx_android_imp.cpp | 34 +- core/src/fxge/apple/apple_int.h | 437 +- core/src/fxge/apple/fx_apple_platform.cpp | 280 +- core/src/fxge/apple/fx_mac_imp.cpp | 149 +- core/src/fxge/apple/fx_quartz_device.cpp | 1994 +++--- core/src/fxge/dib/dib_int.h | 153 +- core/src/fxge/dib/fx_dib_composite.cpp | 9276 +++++++++++++++------------- core/src/fxge/dib/fx_dib_convert.cpp | 1952 +++--- core/src/fxge/dib/fx_dib_engine.cpp | 1660 ++--- core/src/fxge/dib/fx_dib_main.cpp | 3149 +++++----- core/src/fxge/dib/fx_dib_transform.cpp | 1614 ++--- core/src/fxge/ge/fx_ge.cpp | 102 +- core/src/fxge/ge/fx_ge_device.cpp | 759 ++- core/src/fxge/ge/fx_ge_font.cpp | 768 +-- core/src/fxge/ge/fx_ge_fontmap.cpp | 2516 ++++---- core/src/fxge/ge/fx_ge_linux.cpp | 376 +- core/src/fxge/ge/fx_ge_path.cpp | 1236 ++-- core/src/fxge/ge/fx_ge_ps.cpp | 1240 ++-- core/src/fxge/ge/fx_ge_text.cpp | 3438 ++++++----- core/src/fxge/ge/text_int.h | 162 +- core/src/fxge/skia/fx_skia_blitter_new.cpp | 3217 +++++----- core/src/fxge/skia/fx_skia_blitter_new.h | 726 ++- core/src/fxge/skia/fx_skia_device.cpp | 984 +-- core/src/fxge/skia/fx_skia_device.h | 214 +- core/src/fxge/win32/dwrite_int.h | 73 +- core/src/fxge/win32/fx_win32_device.cpp | 2256 +++---- core/src/fxge/win32/fx_win32_dib.cpp | 493 +- core/src/fxge/win32/fx_win32_dwrite.cpp | 746 +-- core/src/fxge/win32/fx_win32_gdipext.cpp | 2465 ++++---- core/src/fxge/win32/fx_win32_print.cpp | 761 +-- core/src/fxge/win32/win32_int.h | 549 +- 41 files changed, 25963 insertions(+), 23011 deletions(-) (limited to 'core/src/fxge') diff --git a/core/src/fxge/agg/include/fx_agg_driver.h b/core/src/fxge/agg/include/fx_agg_driver.h index 29b56c77e4..2954526cd5 100644 --- a/core/src/fxge/agg/include/fx_agg_driver.h +++ b/core/src/fxge/agg/include/fx_agg_driver.h @@ -1,7 +1,7 @@ // Copyright 2014 PDFium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. - + // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com #ifndef FX_AGG_DRIVER_H_ @@ -11,115 +11,146 @@ #include "../../../../../third_party/agg23/agg_path_storage.h" #include "../../../../../third_party/agg23/agg_rasterizer_scanline_aa.h" -class CAgg_PathData -{ -public: - CAgg_PathData() {} - ~CAgg_PathData() {} - FX_NAMESPACE_DECLARE(agg, path_storage) m_PathData; - void BuildPath(const CFX_PathData* pPathData, const CFX_AffineMatrix* pObject2Device); +class CAgg_PathData { + public: + CAgg_PathData() {} + ~CAgg_PathData() {} + FX_NAMESPACE_DECLARE(agg, path_storage) m_PathData; + void BuildPath(const CFX_PathData* pPathData, + const CFX_AffineMatrix* pObject2Device); }; -class CFX_AggDeviceDriver : public IFX_RenderDeviceDriver -{ -public: - CFX_AggDeviceDriver(CFX_DIBitmap* pBitmap, int dither_bits, FX_BOOL bRgbByteOrder, CFX_DIBitmap* pOriDevice, FX_BOOL bGroupKnockout); - virtual ~CFX_AggDeviceDriver(); - void InitPlatform(); - void DestroyPlatform(); - - - virtual int GetDeviceCaps(int caps_id); - - - virtual void SaveState(); - virtual void RestoreState(FX_BOOL bKeepSaved); - - - virtual FX_BOOL SetClip_PathFill(const CFX_PathData* pPathData, - const CFX_AffineMatrix* pObject2Device, - int fill_mode - ); - - - virtual FX_BOOL SetClip_PathStroke(const CFX_PathData* pPathData, - const CFX_AffineMatrix* pObject2Device, - const CFX_GraphStateData* pGraphState - ); - - - virtual FX_BOOL DrawPath(const CFX_PathData* pPathData, +class CFX_AggDeviceDriver : public IFX_RenderDeviceDriver { + public: + CFX_AggDeviceDriver(CFX_DIBitmap* pBitmap, + int dither_bits, + FX_BOOL bRgbByteOrder, + CFX_DIBitmap* pOriDevice, + FX_BOOL bGroupKnockout); + virtual ~CFX_AggDeviceDriver(); + void InitPlatform(); + void DestroyPlatform(); + + virtual int GetDeviceCaps(int caps_id); + + virtual void SaveState(); + virtual void RestoreState(FX_BOOL bKeepSaved); + + virtual FX_BOOL SetClip_PathFill(const CFX_PathData* pPathData, + const CFX_AffineMatrix* pObject2Device, + int fill_mode); + + virtual FX_BOOL SetClip_PathStroke(const CFX_PathData* pPathData, + const CFX_AffineMatrix* pObject2Device, + const CFX_GraphStateData* pGraphState); + + virtual FX_BOOL DrawPath(const CFX_PathData* pPathData, + const CFX_AffineMatrix* pObject2Device, + const CFX_GraphStateData* pGraphState, + FX_DWORD fill_color, + FX_DWORD stroke_color, + int fill_mode, + int alpha_flag, + void* pIccTransform, + int blend_type); + + virtual FX_BOOL SetPixel(int x, + int y, + FX_DWORD color, + int alpha_flag, + void* pIccTransform); + + virtual FX_BOOL FillRect(const FX_RECT* pRect, + FX_DWORD fill_color, + int alpha_flag, + void* pIccTransform, + int blend_type); + + virtual FX_BOOL DrawCosmeticLine(FX_FLOAT x1, + FX_FLOAT y1, + FX_FLOAT x2, + FX_FLOAT y2, + FX_DWORD color, + int alpha_flag, + void* pIccTransform, + int blend_type) { + return FALSE; + } + + virtual FX_BOOL GetClipBox(FX_RECT* pRect); + + virtual FX_BOOL GetDIBits(CFX_DIBitmap* pBitmap, + int left, + int top, + void* pIccTransform = NULL, + FX_BOOL bDEdge = FALSE); + virtual CFX_DIBitmap* GetBackDrop() { return m_pOriDevice; } + + virtual FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap, + FX_DWORD color, + const FX_RECT* pSrcRect, + int left, + int top, + int blend_type, + int alpha_flag, + void* pIccTransform); + virtual FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap, + FX_DWORD color, + int dest_left, + int dest_top, + int dest_width, + int dest_height, + const FX_RECT* pClipRect, + FX_DWORD flags, + int alpha_flag, + void* pIccTransform, + int blend_type); + + virtual FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap, + int bitmap_alpha, + FX_DWORD color, + const CFX_AffineMatrix* pMatrix, + FX_DWORD flags, + void*& handle, + int alpha_flag, + void* pIccTransform, + int blend_type); + virtual FX_BOOL ContinueDIBits(void* handle, IFX_Pause* pPause); + virtual void CancelDIBits(void* handle); + + virtual FX_BOOL DrawDeviceText(int nChars, + const FXTEXT_CHARPOS* pCharPos, + CFX_Font* pFont, + CFX_FontCache* pCache, const CFX_AffineMatrix* pObject2Device, - const CFX_GraphStateData* pGraphState, - FX_DWORD fill_color, - FX_DWORD stroke_color, - int fill_mode, + FX_FLOAT font_size, + FX_DWORD color, int alpha_flag, - void* pIccTransform, - int blend_type - ); - - virtual FX_BOOL SetPixel(int x, int y, FX_DWORD color, - int alpha_flag, void* pIccTransform); - - virtual FX_BOOL FillRect(const FX_RECT* pRect, - FX_DWORD fill_color, int alpha_flag, void* pIccTransform, int blend_type); - - - virtual FX_BOOL DrawCosmeticLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2, FX_DWORD color, - int alpha_flag, void* pIccTransform, int blend_type) - { - return FALSE; - } - - virtual FX_BOOL GetClipBox(FX_RECT* pRect); - - - virtual FX_BOOL GetDIBits(CFX_DIBitmap* pBitmap, int left, int top, void* pIccTransform = NULL, FX_BOOL bDEdge = FALSE); - virtual CFX_DIBitmap* GetBackDrop() - { - return m_pOriDevice; - } - - virtual FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, const FX_RECT* pSrcRect, int left, int top, int blend_type, - int alpha_flag, void* pIccTransform); - virtual FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, int dest_left, int dest_top, - int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags, - int alpha_flag, void* pIccTransform, int blend_type); - - virtual FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap, int bitmap_alpha, FX_DWORD color, - const CFX_AffineMatrix* pMatrix, FX_DWORD flags, void*& handle, - int alpha_flag, void* pIccTransform, int blend_type); - virtual FX_BOOL ContinueDIBits(void* handle, IFX_Pause* pPause); - virtual void CancelDIBits(void* handle); - - virtual FX_BOOL DrawDeviceText(int nChars, const FXTEXT_CHARPOS* pCharPos, CFX_Font* pFont, - CFX_FontCache* pCache, const CFX_AffineMatrix* pObject2Device, FX_FLOAT font_size, FX_DWORD color, - int alpha_flag, void* pIccTransform); - virtual FX_BOOL RenderRasterizer(FX_NAMESPACE_DECLARE(agg, rasterizer_scanline_aa)& rasterizer, FX_DWORD color, FX_BOOL bFullCover, FX_BOOL bGroupKnockout, - int alpha_flag, void* pIccTransform); - - void SetClipMask(FX_NAMESPACE_DECLARE(agg, rasterizer_scanline_aa)& rasterizer); - - virtual uint8_t* GetBuffer() const - { - return m_pBitmap->GetBuffer(); - } - virtual int GetDriverType() - { - return 1; - } - - CFX_DIBitmap* m_pBitmap; - CFX_ClipRgn* m_pClipRgn; - CFX_PtrArray m_StateStack; - void* m_pPlatformGraphics; - void* m_pPlatformBitmap; - void* m_pDwRenderTartget; - int m_FillFlags; - int m_DitherBits; - FX_BOOL m_bRgbByteOrder; - CFX_DIBitmap* m_pOriDevice; - FX_BOOL m_bGroupKnockout; + void* pIccTransform); + virtual FX_BOOL RenderRasterizer( + FX_NAMESPACE_DECLARE(agg, rasterizer_scanline_aa) & rasterizer, + FX_DWORD color, + FX_BOOL bFullCover, + FX_BOOL bGroupKnockout, + int alpha_flag, + void* pIccTransform); + + void SetClipMask(FX_NAMESPACE_DECLARE(agg, rasterizer_scanline_aa) & + rasterizer); + + virtual uint8_t* GetBuffer() const { return m_pBitmap->GetBuffer(); } + virtual int GetDriverType() { return 1; } + + CFX_DIBitmap* m_pBitmap; + CFX_ClipRgn* m_pClipRgn; + CFX_PtrArray m_StateStack; + void* m_pPlatformGraphics; + void* m_pPlatformBitmap; + void* m_pDwRenderTartget; + int m_FillFlags; + int m_DitherBits; + FX_BOOL m_bRgbByteOrder; + CFX_DIBitmap* m_pOriDevice; + FX_BOOL m_bGroupKnockout; }; #endif // FX_AGG_DRIVER_H_ diff --git a/core/src/fxge/agg/src/fx_agg_driver.cpp b/core/src/fxge/agg/src/fx_agg_driver.cpp index 118db7bf1f..fd3ea25096 100644 --- a/core/src/fxge/agg/src/fx_agg_driver.cpp +++ b/core/src/fxge/agg/src/fx_agg_driver.cpp @@ -1,7 +1,7 @@ // Copyright 2014 PDFium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. - + // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com #include "../../../../include/fxge/fx_ge.h" @@ -17,1105 +17,1191 @@ #include "../../../../../third_party/agg23/agg_conv_stroke.h" #include "../../../../../third_party/agg23/agg_conv_dash.h" #include "../include/fx_agg_driver.h" -void _HardClip(FX_FLOAT& x, FX_FLOAT& y) -{ - if (x > 50000) { - x = 50000; - } - if (x < -50000) { - x = -50000; - } - if (y > 50000) { - y = 50000; - } - if (y < -50000) { - y = -50000; - } +void _HardClip(FX_FLOAT& x, FX_FLOAT& y) { + if (x > 50000) { + x = 50000; + } + if (x < -50000) { + x = -50000; + } + if (y > 50000) { + y = 50000; + } + if (y < -50000) { + y = -50000; + } } -void CAgg_PathData::BuildPath(const CFX_PathData* pPathData, const CFX_AffineMatrix* pObject2Device) -{ - int nPoints = pPathData->GetPointCount(); - FX_PATHPOINT* pPoints = pPathData->GetPoints(); - for (int i = 0; i < nPoints; i ++) { - FX_FLOAT x = pPoints[i].m_PointX, y = pPoints[i].m_PointY; - if (pObject2Device) { - pObject2Device->Transform(x, y); - } - _HardClip(x, y); - int point_type = pPoints[i].m_Flag & FXPT_TYPE; - if (point_type == FXPT_MOVETO) { - m_PathData.move_to(x, y); - } else if (point_type == FXPT_LINETO) { - if (pPoints[i - 1].m_Flag == FXPT_MOVETO && (i == nPoints - 1 || pPoints[i + 1].m_Flag == FXPT_MOVETO) && - pPoints[i].m_PointX == pPoints[i - 1].m_PointX && pPoints[i].m_PointY == pPoints[i - 1].m_PointY) { - x += 1; - } - m_PathData.line_to(x, y); - } else if (point_type == FXPT_BEZIERTO) { - FX_FLOAT x0 = pPoints[i - 1].m_PointX, y0 = pPoints[i - 1].m_PointY; - FX_FLOAT x2 = pPoints[i + 1].m_PointX, y2 = pPoints[i + 1].m_PointY; - FX_FLOAT x3 = pPoints[i + 2].m_PointX, y3 = pPoints[i + 2].m_PointY; - if (pObject2Device) { - pObject2Device->Transform(x0, y0); - pObject2Device->Transform(x2, y2); - pObject2Device->Transform(x3, y3); - } - agg::curve4 curve(x0, y0, x, y, x2, y2, x3, y3); - i += 2; - m_PathData.add_path_curve(curve); - } - if (pPoints[i].m_Flag & FXPT_CLOSEFIGURE) { - m_PathData.end_poly(); - } - } +void CAgg_PathData::BuildPath(const CFX_PathData* pPathData, + const CFX_AffineMatrix* pObject2Device) { + int nPoints = pPathData->GetPointCount(); + FX_PATHPOINT* pPoints = pPathData->GetPoints(); + for (int i = 0; i < nPoints; i++) { + FX_FLOAT x = pPoints[i].m_PointX, y = pPoints[i].m_PointY; + if (pObject2Device) { + pObject2Device->Transform(x, y); + } + _HardClip(x, y); + int point_type = pPoints[i].m_Flag & FXPT_TYPE; + if (point_type == FXPT_MOVETO) { + m_PathData.move_to(x, y); + } else if (point_type == FXPT_LINETO) { + if (pPoints[i - 1].m_Flag == FXPT_MOVETO && + (i == nPoints - 1 || pPoints[i + 1].m_Flag == FXPT_MOVETO) && + pPoints[i].m_PointX == pPoints[i - 1].m_PointX && + pPoints[i].m_PointY == pPoints[i - 1].m_PointY) { + x += 1; + } + m_PathData.line_to(x, y); + } else if (point_type == FXPT_BEZIERTO) { + FX_FLOAT x0 = pPoints[i - 1].m_PointX, y0 = pPoints[i - 1].m_PointY; + FX_FLOAT x2 = pPoints[i + 1].m_PointX, y2 = pPoints[i + 1].m_PointY; + FX_FLOAT x3 = pPoints[i + 2].m_PointX, y3 = pPoints[i + 2].m_PointY; + if (pObject2Device) { + pObject2Device->Transform(x0, y0); + pObject2Device->Transform(x2, y2); + pObject2Device->Transform(x3, y3); + } + agg::curve4 curve(x0, y0, x, y, x2, y2, x3, y3); + i += 2; + m_PathData.add_path_curve(curve); + } + if (pPoints[i].m_Flag & FXPT_CLOSEFIGURE) { + m_PathData.end_poly(); + } + } } -namespace agg -{ -template class renderer_scanline_aa_offset -{ -public: - typedef BaseRenderer base_ren_type; - typedef typename base_ren_type::color_type color_type; - renderer_scanline_aa_offset(base_ren_type& ren, unsigned left, unsigned top) : - m_ren(&ren), m_left(left), m_top(top) - {} - void color(const color_type& c) - { - m_color = c; - } - const color_type& color() const - { - return m_color; - } - void prepare(unsigned) {} - template void render(const Scanline& sl) - { - int y = sl.y(); - unsigned num_spans = sl.num_spans(); - typename Scanline::const_iterator span = sl.begin(); - for(;;) { - int x = span->x; - if(span->len > 0) { - m_ren->blend_solid_hspan(x - m_left, y - m_top, (unsigned)span->len, - m_color, - span->covers); - } else { - m_ren->blend_hline(x - m_left, y - m_top, (unsigned)(x - span->len - 1), - m_color, - *(span->covers)); - } - if(--num_spans == 0) { - break; - } - ++span; - } - } -private: - base_ren_type* m_ren; - color_type m_color; - unsigned m_left, m_top; +namespace agg { +template +class renderer_scanline_aa_offset { + public: + typedef BaseRenderer base_ren_type; + typedef typename base_ren_type::color_type color_type; + renderer_scanline_aa_offset(base_ren_type& ren, unsigned left, unsigned top) + : m_ren(&ren), m_left(left), m_top(top) {} + void color(const color_type& c) { m_color = c; } + const color_type& color() const { return m_color; } + void prepare(unsigned) {} + template + void render(const Scanline& sl) { + int y = sl.y(); + unsigned num_spans = sl.num_spans(); + typename Scanline::const_iterator span = sl.begin(); + for (;;) { + int x = span->x; + if (span->len > 0) { + m_ren->blend_solid_hspan(x - m_left, y - m_top, (unsigned)span->len, + m_color, span->covers); + } else { + m_ren->blend_hline(x - m_left, y - m_top, (unsigned)(x - span->len - 1), + m_color, *(span->covers)); + } + if (--num_spans == 0) { + break; + } + ++span; + } + } + + private: + base_ren_type* m_ren; + color_type m_color; + unsigned m_left, m_top; }; } -static void RasterizeStroke(agg::rasterizer_scanline_aa& rasterizer, agg::path_storage& path_data, +static void RasterizeStroke(agg::rasterizer_scanline_aa& rasterizer, + agg::path_storage& path_data, const CFX_AffineMatrix* pObject2Device, - const CFX_GraphStateData* pGraphState, FX_FLOAT scale = 1.0f, - FX_BOOL bStrokeAdjust = FALSE, FX_BOOL bTextMode = FALSE) -{ - agg::line_cap_e cap; - switch (pGraphState->m_LineCap) { - case CFX_GraphStateData::LineCapRound: - cap = agg::round_cap; - break; - case CFX_GraphStateData::LineCapSquare: - cap = agg::square_cap; - break; - default: - cap = agg::butt_cap; - break; - } - agg::line_join_e join; - switch (pGraphState->m_LineJoin) { - case CFX_GraphStateData::LineJoinRound: - join = agg::round_join; - break; - case CFX_GraphStateData::LineJoinBevel: - join = agg::bevel_join; - break; - default: - join = agg::miter_join_revert; - break; - } - FX_FLOAT width = pGraphState->m_LineWidth * scale; - FX_FLOAT unit = 1.f; - if (pObject2Device) { - unit = FXSYS_Div(1.0f, (pObject2Device->GetXUnit() + pObject2Device->GetYUnit()) / 2); - } - if (width < unit) { - width = unit; - } - if (pGraphState->m_DashArray == NULL) { - agg::conv_stroke stroke(path_data); - stroke.line_join(join); - stroke.line_cap(cap); - stroke.miter_limit(pGraphState->m_MiterLimit); - stroke.width(width); - rasterizer.add_path_transformed(stroke, pObject2Device); - } else { - typedef agg::conv_dash dash_converter; - dash_converter dash(path_data); - for (int i = 0; i < (pGraphState->m_DashCount + 1) / 2; i ++) { - FX_FLOAT on = pGraphState->m_DashArray[i * 2]; - if (on <= 0.000001f) { - on = 1.0f / 10; - } - FX_FLOAT off = i * 2 + 1 == pGraphState->m_DashCount ? on : - pGraphState->m_DashArray[i * 2 + 1]; - if (off < 0) { - off = 0; - } - dash.add_dash(on * scale, off * scale); - } - dash.dash_start(pGraphState->m_DashPhase * scale); - typedef agg::conv_stroke dash_stroke; - dash_stroke stroke(dash); - stroke.line_join(join); - stroke.line_cap(cap); - stroke.miter_limit(pGraphState->m_MiterLimit); - stroke.width(width); - rasterizer.add_path_transformed(stroke, pObject2Device); - } -} -IFX_RenderDeviceDriver* IFX_RenderDeviceDriver::CreateFxgeDriver(CFX_DIBitmap* pBitmap, FX_BOOL bRgbByteOrder, CFX_DIBitmap* pOriDevice, FX_BOOL bGroupKnockout) -{ - return new CFX_AggDeviceDriver(pBitmap, 0, bRgbByteOrder, pOriDevice, bGroupKnockout); -} -CFX_AggDeviceDriver::CFX_AggDeviceDriver(CFX_DIBitmap* pBitmap, int dither_bits, FX_BOOL bRgbByteOrder, CFX_DIBitmap* pOriDevice, FX_BOOL bGroupKnockout) -{ - m_pBitmap = pBitmap; - m_DitherBits = dither_bits; - m_pClipRgn = NULL; - m_pPlatformBitmap = NULL; - m_pPlatformGraphics = NULL; - m_pDwRenderTartget = NULL; - m_bRgbByteOrder = bRgbByteOrder; - m_pOriDevice = pOriDevice; - m_bGroupKnockout = bGroupKnockout; - m_FillFlags = 0; - InitPlatform(); + const CFX_GraphStateData* pGraphState, + FX_FLOAT scale = 1.0f, + FX_BOOL bStrokeAdjust = FALSE, + FX_BOOL bTextMode = FALSE) { + agg::line_cap_e cap; + switch (pGraphState->m_LineCap) { + case CFX_GraphStateData::LineCapRound: + cap = agg::round_cap; + break; + case CFX_GraphStateData::LineCapSquare: + cap = agg::square_cap; + break; + default: + cap = agg::butt_cap; + break; + } + agg::line_join_e join; + switch (pGraphState->m_LineJoin) { + case CFX_GraphStateData::LineJoinRound: + join = agg::round_join; + break; + case CFX_GraphStateData::LineJoinBevel: + join = agg::bevel_join; + break; + default: + join = agg::miter_join_revert; + break; + } + FX_FLOAT width = pGraphState->m_LineWidth * scale; + FX_FLOAT unit = 1.f; + if (pObject2Device) { + unit = FXSYS_Div( + 1.0f, (pObject2Device->GetXUnit() + pObject2Device->GetYUnit()) / 2); + } + if (width < unit) { + width = unit; + } + if (pGraphState->m_DashArray == NULL) { + agg::conv_stroke stroke(path_data); + stroke.line_join(join); + stroke.line_cap(cap); + stroke.miter_limit(pGraphState->m_MiterLimit); + stroke.width(width); + rasterizer.add_path_transformed(stroke, pObject2Device); + } else { + typedef agg::conv_dash dash_converter; + dash_converter dash(path_data); + for (int i = 0; i < (pGraphState->m_DashCount + 1) / 2; i++) { + FX_FLOAT on = pGraphState->m_DashArray[i * 2]; + if (on <= 0.000001f) { + on = 1.0f / 10; + } + FX_FLOAT off = i * 2 + 1 == pGraphState->m_DashCount + ? on + : pGraphState->m_DashArray[i * 2 + 1]; + if (off < 0) { + off = 0; + } + dash.add_dash(on * scale, off * scale); + } + dash.dash_start(pGraphState->m_DashPhase * scale); + typedef agg::conv_stroke dash_stroke; + dash_stroke stroke(dash); + stroke.line_join(join); + stroke.line_cap(cap); + stroke.miter_limit(pGraphState->m_MiterLimit); + stroke.width(width); + rasterizer.add_path_transformed(stroke, pObject2Device); + } } -CFX_AggDeviceDriver::~CFX_AggDeviceDriver() -{ - delete m_pClipRgn; - for (int i = 0; i < m_StateStack.GetSize(); i ++) - delete (CFX_ClipRgn*)m_StateStack[i]; - DestroyPlatform(); +IFX_RenderDeviceDriver* IFX_RenderDeviceDriver::CreateFxgeDriver( + CFX_DIBitmap* pBitmap, + FX_BOOL bRgbByteOrder, + CFX_DIBitmap* pOriDevice, + FX_BOOL bGroupKnockout) { + return new CFX_AggDeviceDriver(pBitmap, 0, bRgbByteOrder, pOriDevice, + bGroupKnockout); } -#if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_ -void CFX_AggDeviceDriver::InitPlatform() -{ +CFX_AggDeviceDriver::CFX_AggDeviceDriver(CFX_DIBitmap* pBitmap, + int dither_bits, + FX_BOOL bRgbByteOrder, + CFX_DIBitmap* pOriDevice, + FX_BOOL bGroupKnockout) { + m_pBitmap = pBitmap; + m_DitherBits = dither_bits; + m_pClipRgn = NULL; + m_pPlatformBitmap = NULL; + m_pPlatformGraphics = NULL; + m_pDwRenderTartget = NULL; + m_bRgbByteOrder = bRgbByteOrder; + m_pOriDevice = pOriDevice; + m_bGroupKnockout = bGroupKnockout; + m_FillFlags = 0; + InitPlatform(); } -void CFX_AggDeviceDriver::DestroyPlatform() -{ +CFX_AggDeviceDriver::~CFX_AggDeviceDriver() { + delete m_pClipRgn; + for (int i = 0; i < m_StateStack.GetSize(); i++) + delete (CFX_ClipRgn*)m_StateStack[i]; + DestroyPlatform(); } -FX_BOOL CFX_AggDeviceDriver::DrawDeviceText(int nChars, const FXTEXT_CHARPOS* pCharPos, CFX_Font* pFont, - CFX_FontCache* pCache, const CFX_AffineMatrix* pObject2Device, FX_FLOAT font_size, FX_DWORD color, - int alpha_flag, void* pIccTransform) -{ - return FALSE; +#if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_ +void CFX_AggDeviceDriver::InitPlatform() {} +void CFX_AggDeviceDriver::DestroyPlatform() {} +FX_BOOL CFX_AggDeviceDriver::DrawDeviceText( + int nChars, + const FXTEXT_CHARPOS* pCharPos, + CFX_Font* pFont, + CFX_FontCache* pCache, + const CFX_AffineMatrix* pObject2Device, + FX_FLOAT font_size, + FX_DWORD color, + int alpha_flag, + void* pIccTransform) { + return FALSE; } #endif -int CFX_AggDeviceDriver::GetDeviceCaps(int caps_id) -{ - switch (caps_id) { - case FXDC_DEVICE_CLASS: - return FXDC_DISPLAY; - case FXDC_PIXEL_WIDTH: - return m_pBitmap->GetWidth(); - case FXDC_PIXEL_HEIGHT: - return m_pBitmap->GetHeight(); - case FXDC_BITS_PIXEL: - return m_pBitmap->GetBPP(); - case FXDC_HORZ_SIZE: - case FXDC_VERT_SIZE: - return 0; - case FXDC_RENDER_CAPS: { - int flags = FXRC_GET_BITS | FXRC_ALPHA_PATH | FXRC_ALPHA_IMAGE | FXRC_BLEND_MODE | FXRC_SOFT_CLIP; - if (m_pBitmap->HasAlpha()) { - flags |= FXRC_ALPHA_OUTPUT; - } else if (m_pBitmap->IsAlphaMask()) { - if (m_pBitmap->GetBPP() == 1) { - flags |= FXRC_BITMASK_OUTPUT; - } else { - flags |= FXRC_BYTEMASK_OUTPUT; - } - } - if (m_pBitmap->IsCmykImage()) { - flags |= FXRC_CMYK_OUTPUT; - } - return flags; - } - case FXDC_DITHER_BITS: - return m_DitherBits; - } - return 0; +int CFX_AggDeviceDriver::GetDeviceCaps(int caps_id) { + switch (caps_id) { + case FXDC_DEVICE_CLASS: + return FXDC_DISPLAY; + case FXDC_PIXEL_WIDTH: + return m_pBitmap->GetWidth(); + case FXDC_PIXEL_HEIGHT: + return m_pBitmap->GetHeight(); + case FXDC_BITS_PIXEL: + return m_pBitmap->GetBPP(); + case FXDC_HORZ_SIZE: + case FXDC_VERT_SIZE: + return 0; + case FXDC_RENDER_CAPS: { + int flags = FXRC_GET_BITS | FXRC_ALPHA_PATH | FXRC_ALPHA_IMAGE | + FXRC_BLEND_MODE | FXRC_SOFT_CLIP; + if (m_pBitmap->HasAlpha()) { + flags |= FXRC_ALPHA_OUTPUT; + } else if (m_pBitmap->IsAlphaMask()) { + if (m_pBitmap->GetBPP() == 1) { + flags |= FXRC_BITMASK_OUTPUT; + } else { + flags |= FXRC_BYTEMASK_OUTPUT; + } + } + if (m_pBitmap->IsCmykImage()) { + flags |= FXRC_CMYK_OUTPUT; + } + return flags; + } + case FXDC_DITHER_BITS: + return m_DitherBits; + } + return 0; } -void CFX_AggDeviceDriver::SaveState() -{ - void* pClip = NULL; - if (m_pClipRgn) { - pClip = new CFX_ClipRgn(*m_pClipRgn); - } - m_StateStack.Add(pClip); +void CFX_AggDeviceDriver::SaveState() { + void* pClip = NULL; + if (m_pClipRgn) { + pClip = new CFX_ClipRgn(*m_pClipRgn); + } + m_StateStack.Add(pClip); } -void CFX_AggDeviceDriver::RestoreState(FX_BOOL bKeepSaved) -{ - if (m_StateStack.GetSize() == 0) { - delete m_pClipRgn; - m_pClipRgn = NULL; - return; - } - CFX_ClipRgn* pSavedClip = (CFX_ClipRgn*)m_StateStack[m_StateStack.GetSize() - 1]; +void CFX_AggDeviceDriver::RestoreState(FX_BOOL bKeepSaved) { + if (m_StateStack.GetSize() == 0) { delete m_pClipRgn; m_pClipRgn = NULL; - if (bKeepSaved) { - if (pSavedClip) { - m_pClipRgn = new CFX_ClipRgn(*pSavedClip); - } - } else { - m_StateStack.RemoveAt(m_StateStack.GetSize() - 1); - m_pClipRgn = pSavedClip; - } + return; + } + CFX_ClipRgn* pSavedClip = + (CFX_ClipRgn*)m_StateStack[m_StateStack.GetSize() - 1]; + delete m_pClipRgn; + m_pClipRgn = NULL; + if (bKeepSaved) { + if (pSavedClip) { + m_pClipRgn = new CFX_ClipRgn(*pSavedClip); + } + } else { + m_StateStack.RemoveAt(m_StateStack.GetSize() - 1); + m_pClipRgn = pSavedClip; + } } -void CFX_AggDeviceDriver::SetClipMask(agg::rasterizer_scanline_aa& rasterizer) -{ - FX_RECT path_rect(rasterizer.min_x(), rasterizer.min_y(), - rasterizer.max_x() + 1, rasterizer.max_y() + 1); - path_rect.Intersect(m_pClipRgn->GetBox()); - CFX_DIBitmapRef mask; - CFX_DIBitmap* pThisLayer = mask.New(); - if (!pThisLayer) { - return; - } - pThisLayer->Create(path_rect.Width(), path_rect.Height(), FXDIB_8bppMask); - pThisLayer->Clear(0); - agg::rendering_buffer raw_buf(pThisLayer->GetBuffer(), pThisLayer->GetWidth(), pThisLayer->GetHeight(), pThisLayer->GetPitch()); - agg::pixfmt_gray8 pixel_buf(raw_buf); - agg::renderer_base base_buf(pixel_buf); - agg::renderer_scanline_aa_offset > final_render(base_buf, path_rect.left, path_rect.top); - final_render.color(agg::gray8(255)); - agg::scanline_u8 scanline; - agg::render_scanlines(rasterizer, scanline, final_render, (m_FillFlags & FXFILL_NOPATHSMOOTH) != 0); - m_pClipRgn->IntersectMaskF(path_rect.left, path_rect.top, mask); +void CFX_AggDeviceDriver::SetClipMask(agg::rasterizer_scanline_aa& rasterizer) { + FX_RECT path_rect(rasterizer.min_x(), rasterizer.min_y(), + rasterizer.max_x() + 1, rasterizer.max_y() + 1); + path_rect.Intersect(m_pClipRgn->GetBox()); + CFX_DIBitmapRef mask; + CFX_DIBitmap* pThisLayer = mask.New(); + if (!pThisLayer) { + return; + } + pThisLayer->Create(path_rect.Width(), path_rect.Height(), FXDIB_8bppMask); + pThisLayer->Clear(0); + agg::rendering_buffer raw_buf(pThisLayer->GetBuffer(), pThisLayer->GetWidth(), + pThisLayer->GetHeight(), + pThisLayer->GetPitch()); + agg::pixfmt_gray8 pixel_buf(raw_buf); + agg::renderer_base base_buf(pixel_buf); + agg::renderer_scanline_aa_offset > + final_render(base_buf, path_rect.left, path_rect.top); + final_render.color(agg::gray8(255)); + agg::scanline_u8 scanline; + agg::render_scanlines(rasterizer, scanline, final_render, + (m_FillFlags & FXFILL_NOPATHSMOOTH) != 0); + m_pClipRgn->IntersectMaskF(path_rect.left, path_rect.top, mask); } -FX_BOOL CFX_AggDeviceDriver::SetClip_PathFill(const CFX_PathData* pPathData, - const CFX_AffineMatrix* pObject2Device, - int fill_mode - ) -{ - m_FillFlags = fill_mode; - if (m_pClipRgn == NULL) { - m_pClipRgn = new CFX_ClipRgn(GetDeviceCaps(FXDC_PIXEL_WIDTH), GetDeviceCaps(FXDC_PIXEL_HEIGHT)); - } - if (pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) { - CFX_FloatRect rectf; - if (pPathData->IsRect(pObject2Device, &rectf)) { - rectf.Intersect(CFX_FloatRect(0, 0, (FX_FLOAT)GetDeviceCaps(FXDC_PIXEL_WIDTH), (FX_FLOAT)GetDeviceCaps(FXDC_PIXEL_HEIGHT))); - FX_RECT rect = rectf.GetOutterRect(); - m_pClipRgn->IntersectRect(rect); - return TRUE; - } - } - CAgg_PathData path_data; - path_data.BuildPath(pPathData, pObject2Device); - path_data.m_PathData.end_poly(); - agg::rasterizer_scanline_aa rasterizer; - rasterizer.clip_box(0.0f, 0.0f, (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_WIDTH)), (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_HEIGHT))); - rasterizer.add_path(path_data.m_PathData); - rasterizer.filling_rule((fill_mode & 3) == FXFILL_WINDING ? agg::fill_non_zero : agg::fill_even_odd); - SetClipMask(rasterizer); - return TRUE; +FX_BOOL CFX_AggDeviceDriver::SetClip_PathFill( + const CFX_PathData* pPathData, + const CFX_AffineMatrix* pObject2Device, + int fill_mode) { + m_FillFlags = fill_mode; + if (m_pClipRgn == NULL) { + m_pClipRgn = new CFX_ClipRgn(GetDeviceCaps(FXDC_PIXEL_WIDTH), + GetDeviceCaps(FXDC_PIXEL_HEIGHT)); + } + if (pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) { + CFX_FloatRect rectf; + if (pPathData->IsRect(pObject2Device, &rectf)) { + rectf.Intersect( + CFX_FloatRect(0, 0, (FX_FLOAT)GetDeviceCaps(FXDC_PIXEL_WIDTH), + (FX_FLOAT)GetDeviceCaps(FXDC_PIXEL_HEIGHT))); + FX_RECT rect = rectf.GetOutterRect(); + m_pClipRgn->IntersectRect(rect); + return TRUE; + } + } + CAgg_PathData path_data; + path_data.BuildPath(pPathData, pObject2Device); + path_data.m_PathData.end_poly(); + agg::rasterizer_scanline_aa rasterizer; + rasterizer.clip_box(0.0f, 0.0f, (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_WIDTH)), + (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_HEIGHT))); + rasterizer.add_path(path_data.m_PathData); + rasterizer.filling_rule((fill_mode & 3) == FXFILL_WINDING + ? agg::fill_non_zero + : agg::fill_even_odd); + SetClipMask(rasterizer); + return TRUE; } -FX_BOOL CFX_AggDeviceDriver::SetClip_PathStroke(const CFX_PathData* pPathData, - const CFX_AffineMatrix* pObject2Device, - const CFX_GraphStateData* pGraphState - ) -{ - if (m_pClipRgn == NULL) { - m_pClipRgn = new CFX_ClipRgn(GetDeviceCaps(FXDC_PIXEL_WIDTH), GetDeviceCaps(FXDC_PIXEL_HEIGHT)); - } - CAgg_PathData path_data; - path_data.BuildPath(pPathData, NULL); - agg::rasterizer_scanline_aa rasterizer; - rasterizer.clip_box(0.0f, 0.0f, (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_WIDTH)), (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_HEIGHT))); - RasterizeStroke(rasterizer, path_data.m_PathData, pObject2Device, pGraphState); - rasterizer.filling_rule(agg::fill_non_zero); - SetClipMask(rasterizer); - return TRUE; +FX_BOOL CFX_AggDeviceDriver::SetClip_PathStroke( + const CFX_PathData* pPathData, + const CFX_AffineMatrix* pObject2Device, + const CFX_GraphStateData* pGraphState) { + if (m_pClipRgn == NULL) { + m_pClipRgn = new CFX_ClipRgn(GetDeviceCaps(FXDC_PIXEL_WIDTH), + GetDeviceCaps(FXDC_PIXEL_HEIGHT)); + } + CAgg_PathData path_data; + path_data.BuildPath(pPathData, NULL); + agg::rasterizer_scanline_aa rasterizer; + rasterizer.clip_box(0.0f, 0.0f, (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_WIDTH)), + (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_HEIGHT))); + RasterizeStroke(rasterizer, path_data.m_PathData, pObject2Device, + pGraphState); + rasterizer.filling_rule(agg::fill_non_zero); + SetClipMask(rasterizer); + return TRUE; } -class CFX_Renderer -{ -private: - int m_Alpha, - m_Red, - m_Green, - m_Blue, - m_Gray; - FX_DWORD m_Color; - FX_BOOL m_bFullCover; - FX_BOOL m_bRgbByteOrder; - CFX_DIBitmap* m_pOriDevice; - FX_RECT m_ClipBox; - const CFX_DIBitmap* m_pClipMask; - CFX_DIBitmap* m_pDevice; - const CFX_ClipRgn* m_pClipRgn; - void (CFX_Renderer::*composite_span)(uint8_t*, int, int, int, uint8_t*, int, int, uint8_t*, uint8_t*); -public: - void prepare(unsigned) {} - void CompositeSpan(uint8_t* dest_scan, uint8_t* ori_scan, int Bpp, FX_BOOL bDestAlpha, - int span_left, int span_len, uint8_t* cover_scan, - int clip_left, int clip_right, uint8_t* clip_scan) - { - ASSERT(!m_pDevice->IsCmykImage()); - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - if (Bpp) { - dest_scan += col_start * Bpp; - ori_scan += col_start * Bpp; - } else { - dest_scan += col_start / 8; - ori_scan += col_start / 8; +class CFX_Renderer { + private: + int m_Alpha, m_Red, m_Green, m_Blue, m_Gray; + FX_DWORD m_Color; + FX_BOOL m_bFullCover; + FX_BOOL m_bRgbByteOrder; + CFX_DIBitmap* m_pOriDevice; + FX_RECT m_ClipBox; + const CFX_DIBitmap* m_pClipMask; + CFX_DIBitmap* m_pDevice; + const CFX_ClipRgn* m_pClipRgn; + void (CFX_Renderer::*composite_span)(uint8_t*, + int, + int, + int, + uint8_t*, + int, + int, + uint8_t*, + uint8_t*); + + public: + void prepare(unsigned) {} + void CompositeSpan(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + FX_BOOL bDestAlpha, + int span_left, + int span_len, + uint8_t* cover_scan, + int clip_left, + int clip_right, + uint8_t* clip_scan) { + ASSERT(!m_pDevice->IsCmykImage()); + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = (span_left + span_len) < clip_right + ? span_len + : (clip_right - span_left); + if (Bpp) { + dest_scan += col_start * Bpp; + ori_scan += col_start * Bpp; + } else { + dest_scan += col_start / 8; + ori_scan += col_start / 8; + } + if (m_bRgbByteOrder) { + if (Bpp == 4 && bDestAlpha) { + for (int col = col_start; col < col_end; col++) { + int src_alpha; + if (clip_scan) { + src_alpha = m_Alpha * clip_scan[col] / 255; + } else { + src_alpha = m_Alpha; + } + uint8_t dest_alpha = + ori_scan[3] + src_alpha - ori_scan[3] * src_alpha / 255; + dest_scan[3] = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + if (m_bFullCover) { + *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Red, alpha_ratio); + *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, alpha_ratio); + *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, alpha_ratio); + dest_scan++; + ori_scan++; + } else { + int r = FXDIB_ALPHA_MERGE(*ori_scan++, m_Red, alpha_ratio); + int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, alpha_ratio); + int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, alpha_ratio); + ori_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan[col]); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan[col]); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan[col]); + dest_scan += 2; + } } - if (m_bRgbByteOrder) { - if (Bpp == 4 && bDestAlpha) { - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (clip_scan) { - src_alpha = m_Alpha * clip_scan[col] / 255; - } else { - src_alpha = m_Alpha; - } - uint8_t dest_alpha = ori_scan[3] + src_alpha - ori_scan[3] * src_alpha / 255; - dest_scan[3] = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - if (m_bFullCover) { - *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Red, alpha_ratio); - *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, alpha_ratio); - *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, alpha_ratio); - dest_scan++; - ori_scan++; - } else { - int r = FXDIB_ALPHA_MERGE(*ori_scan++, m_Red, alpha_ratio); - int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, alpha_ratio); - int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, alpha_ratio); - ori_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE( *dest_scan, r, cover_scan[col]); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan[col]); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan[col]); - dest_scan += 2; - } - } - return; - } - if (Bpp == 3 || Bpp == 4) { - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (clip_scan) { - src_alpha = m_Alpha * clip_scan[col] / 255 ; - } else { - src_alpha = m_Alpha; - } - int r = FXDIB_ALPHA_MERGE(*ori_scan++, m_Red, src_alpha); - int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); - int b = FXDIB_ALPHA_MERGE(*ori_scan, m_Blue, src_alpha); - ori_scan += Bpp - 2; - *dest_scan = FXDIB_ALPHA_MERGE( *dest_scan, r, cover_scan[col]); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan[col]); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan[col]); - dest_scan += Bpp - 2; - } - } - return; + return; + } + if (Bpp == 3 || Bpp == 4) { + for (int col = col_start; col < col_end; col++) { + int src_alpha; + if (clip_scan) { + src_alpha = m_Alpha * clip_scan[col] / 255; + } else { + src_alpha = m_Alpha; + } + int r = FXDIB_ALPHA_MERGE(*ori_scan++, m_Red, src_alpha); + int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); + int b = FXDIB_ALPHA_MERGE(*ori_scan, m_Blue, src_alpha); + ori_scan += Bpp - 2; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan[col]); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan[col]); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan[col]); + dest_scan += Bpp - 2; } - if (Bpp == 4 && bDestAlpha) { - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (clip_scan) { - src_alpha = m_Alpha * clip_scan[col] / 255; - } else { - src_alpha = m_Alpha; - } - int src_alpha_covered = src_alpha * cover_scan[col] / 255; - if (src_alpha_covered == 0) { - dest_scan += 4; - continue; - } - if (cover_scan[col] == 255) { - dest_scan[3] = src_alpha_covered; - *dest_scan ++ = m_Blue; - *dest_scan ++ = m_Green; - *dest_scan = m_Red; - dest_scan += 2; - continue; - } else { - if (dest_scan[3] == 0) { - dest_scan[3] = src_alpha_covered; - *dest_scan ++ = m_Blue; - *dest_scan ++ = m_Green; - *dest_scan = m_Red; - dest_scan += 2; - continue; - } - uint8_t cover = cover_scan[col]; - dest_scan[3] = FXDIB_ALPHA_MERGE(dest_scan[3], src_alpha, cover); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, cover); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, cover); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, cover); - dest_scan += 2; - } - } - return; + } + return; + } + if (Bpp == 4 && bDestAlpha) { + for (int col = col_start; col < col_end; col++) { + int src_alpha; + if (clip_scan) { + src_alpha = m_Alpha * clip_scan[col] / 255; + } else { + src_alpha = m_Alpha; } - if (Bpp == 3 || Bpp == 4) { - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (clip_scan) { - src_alpha = m_Alpha * clip_scan[col] / 255; - } else { - src_alpha = m_Alpha; - } - if (m_bFullCover) { - *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); - *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); - *dest_scan = FXDIB_ALPHA_MERGE(*ori_scan, m_Red, src_alpha); - dest_scan += Bpp - 2; - ori_scan += Bpp - 2; - continue; - } - int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); - int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); - int r = FXDIB_ALPHA_MERGE(*ori_scan, m_Red, src_alpha); - ori_scan += Bpp - 2; - *dest_scan = FXDIB_ALPHA_MERGE( *dest_scan, b, cover_scan[col]); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan[col]); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan[col]); - dest_scan += Bpp - 2; - continue; - } - return; + int src_alpha_covered = src_alpha * cover_scan[col] / 255; + if (src_alpha_covered == 0) { + dest_scan += 4; + continue; } - if (Bpp == 1) { - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (clip_scan) { - src_alpha = m_Alpha * clip_scan[col] / 255; - } else { - src_alpha = m_Alpha; - } - if (m_bFullCover) { - *dest_scan = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha); - } else { - int gray = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, cover_scan[col]); - dest_scan++; - } - } + if (cover_scan[col] == 255) { + dest_scan[3] = src_alpha_covered; + *dest_scan++ = m_Blue; + *dest_scan++ = m_Green; + *dest_scan = m_Red; + dest_scan += 2; + continue; } else { - int index = 0; - if (m_pDevice->GetPalette() == NULL) { - index = ((uint8_t)m_Color == 0xff) ? 1 : 0; - } else { - for (int i = 0; i < 2; i ++) - if (FXARGB_TODIB(m_pDevice->GetPalette()[i]) == m_Color) { - index = i; - } - } - uint8_t* dest_scan1 = dest_scan; - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (clip_scan) { - src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; - } else { - src_alpha = m_Alpha * cover_scan[col] / 255; - } - if (src_alpha) { - if (!index) { - *dest_scan1 &= ~(1 << (7 - (col + span_left) % 8)); - } else { - *dest_scan1 |= 1 << (7 - (col + span_left) % 8); - } - } - dest_scan1 = dest_scan + (span_left % 8 + col - col_start + 1) / 8; - } + if (dest_scan[3] == 0) { + dest_scan[3] = src_alpha_covered; + *dest_scan++ = m_Blue; + *dest_scan++ = m_Green; + *dest_scan = m_Red; + dest_scan += 2; + continue; + } + uint8_t cover = cover_scan[col]; + dest_scan[3] = FXDIB_ALPHA_MERGE(dest_scan[3], src_alpha, cover); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, cover); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, cover); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, cover); + dest_scan += 2; } - } - void CompositeSpan1bpp(uint8_t* dest_scan, int Bpp, - int span_left, int span_len, uint8_t* cover_scan, - int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan) - { - ASSERT(!m_bRgbByteOrder); - ASSERT(!m_pDevice->IsCmykImage()); - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - dest_scan += col_start / 8; - int index = 0; - if (m_pDevice->GetPalette() == NULL) { - index = ((uint8_t)m_Color == 0xff) ? 1 : 0; + } + return; + } + if (Bpp == 3 || Bpp == 4) { + for (int col = col_start; col < col_end; col++) { + int src_alpha; + if (clip_scan) { + src_alpha = m_Alpha * clip_scan[col] / 255; } else { - for (int i = 0; i < 2; i ++) - if (FXARGB_TODIB(m_pDevice->GetPalette()[i]) == m_Color) { - index = i; - } + src_alpha = m_Alpha; } - uint8_t* dest_scan1 = dest_scan; - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (clip_scan) { - src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; - } else { - src_alpha = m_Alpha * cover_scan[col] / 255; - } - if (src_alpha) { - if (!index) { - *dest_scan1 &= ~(1 << (7 - (col + span_left) % 8)); - } else { - *dest_scan1 |= 1 << (7 - (col + span_left) % 8); - } - } - dest_scan1 = dest_scan + (span_left % 8 + col - col_start + 1) / 8; + if (m_bFullCover) { + *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); + *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); + *dest_scan = FXDIB_ALPHA_MERGE(*ori_scan, m_Red, src_alpha); + dest_scan += Bpp - 2; + ori_scan += Bpp - 2; + continue; } - } - void CompositeSpanGray(uint8_t* dest_scan, int Bpp, - int span_left, int span_len, uint8_t* cover_scan, - int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan) - { - ASSERT(!m_bRgbByteOrder); - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - dest_scan += col_start; - if (dest_extra_alpha_scan) { - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (m_bFullCover) { - if (clip_scan) { - src_alpha = m_Alpha * clip_scan[col] / 255; - } else { - src_alpha = m_Alpha; - } - } else { - if (clip_scan) { - src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; - } else { - src_alpha = m_Alpha * cover_scan[col] / 255; - } - } - if (src_alpha) { - if (src_alpha == 255) { - *dest_scan = m_Gray; - *dest_extra_alpha_scan = m_Alpha; - } else { - uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha - - (*dest_extra_alpha_scan) * src_alpha / 255; - *dest_extra_alpha_scan++ = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, alpha_ratio); - dest_scan ++; - continue; - } - } - dest_extra_alpha_scan ++; - dest_scan ++; - } + int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); + int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); + int r = FXDIB_ALPHA_MERGE(*ori_scan, m_Red, src_alpha); + ori_scan += Bpp - 2; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan[col]); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan[col]); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan[col]); + dest_scan += Bpp - 2; + continue; + } + return; + } + if (Bpp == 1) { + for (int col = col_start; col < col_end; col++) { + int src_alpha; + if (clip_scan) { + src_alpha = m_Alpha * clip_scan[col] / 255; } else { - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (clip_scan) { - src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; - } else { - src_alpha = m_Alpha * cover_scan[col] / 255; - } - if (src_alpha) { - if (src_alpha == 255) { - *dest_scan = m_Gray; - } else { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, src_alpha); - } - } - dest_scan ++; - } + src_alpha = m_Alpha; } - } - void CompositeSpanARGB(uint8_t* dest_scan, int Bpp, - int span_left, int span_len, uint8_t* cover_scan, - int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan) - { - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - dest_scan += col_start * Bpp; - if (m_bRgbByteOrder) { - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (m_bFullCover) { - if (clip_scan) { - src_alpha = m_Alpha * clip_scan[col] / 255; - } else { - src_alpha = m_Alpha; - } - } else { - if (clip_scan) { - src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; - } else { - src_alpha = m_Alpha * cover_scan[col] / 255; - } - } - if (src_alpha) { - if (src_alpha == 255) { - *(FX_DWORD*)dest_scan = m_Color; - } else { - uint8_t dest_alpha = dest_scan[3] + src_alpha - dest_scan[3] * src_alpha / 255; - dest_scan[3] = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); - dest_scan += 2; - continue; - } - } - dest_scan += 4; - } - return; + if (m_bFullCover) { + *dest_scan = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha); + } else { + int gray = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, cover_scan[col]); + dest_scan++; } - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (m_bFullCover) { - if (clip_scan) { - src_alpha = m_Alpha * clip_scan[col] / 255; - } else { - src_alpha = m_Alpha; - } - } else { - if (clip_scan) { - src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; - } else { - src_alpha = m_Alpha * cover_scan[col] / 255; - } - } - if (src_alpha) { - if (src_alpha == 255) { - *(FX_DWORD*)dest_scan = m_Color; - } else { - if (dest_scan[3] == 0) { - dest_scan[3] = src_alpha; - *dest_scan++ = m_Blue; - *dest_scan++ = m_Green; - *dest_scan = m_Red; - dest_scan += 2; - continue; - } - uint8_t dest_alpha = dest_scan[3] + src_alpha - dest_scan[3] * src_alpha / 255; - dest_scan[3] = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); - dest_scan += 2; - continue; - } - } - dest_scan += Bpp; + } + } else { + int index = 0; + if (m_pDevice->GetPalette() == NULL) { + index = ((uint8_t)m_Color == 0xff) ? 1 : 0; + } else { + for (int i = 0; i < 2; i++) + if (FXARGB_TODIB(m_pDevice->GetPalette()[i]) == m_Color) { + index = i; + } + } + uint8_t* dest_scan1 = dest_scan; + for (int col = col_start; col < col_end; col++) { + int src_alpha; + if (clip_scan) { + src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; + } else { + src_alpha = m_Alpha * cover_scan[col] / 255; + } + if (src_alpha) { + if (!index) { + *dest_scan1 &= ~(1 << (7 - (col + span_left) % 8)); + } else { + *dest_scan1 |= 1 << (7 - (col + span_left) % 8); + } + } + dest_scan1 = dest_scan + (span_left % 8 + col - col_start + 1) / 8; + } + } + } + void CompositeSpan1bpp(uint8_t* dest_scan, + int Bpp, + int span_left, + int span_len, + uint8_t* cover_scan, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan) { + ASSERT(!m_bRgbByteOrder); + ASSERT(!m_pDevice->IsCmykImage()); + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = (span_left + span_len) < clip_right + ? span_len + : (clip_right - span_left); + dest_scan += col_start / 8; + int index = 0; + if (m_pDevice->GetPalette() == NULL) { + index = ((uint8_t)m_Color == 0xff) ? 1 : 0; + } else { + for (int i = 0; i < 2; i++) + if (FXARGB_TODIB(m_pDevice->GetPalette()[i]) == m_Color) { + index = i; } } - void CompositeSpanRGB(uint8_t* dest_scan, int Bpp, - int span_left, int span_len, uint8_t* cover_scan, - int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan) - { - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - dest_scan += col_start * Bpp; - if (m_bRgbByteOrder) { - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (clip_scan) { - src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; - } else { - src_alpha = m_Alpha * cover_scan[col] / 255; - } - if (src_alpha) { - if (src_alpha == 255) { - if (Bpp == 4) { - *(FX_DWORD*)dest_scan = m_Color; - } else if (Bpp == 3) { - *dest_scan++ = m_Red; - *dest_scan++ = m_Green; - *dest_scan++ = m_Blue; - continue; - } - } else { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha); - dest_scan++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha); - dest_scan++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha); - dest_scan += Bpp - 2; - continue; - } - } - dest_scan += Bpp; - } - return; + uint8_t* dest_scan1 = dest_scan; + for (int col = col_start; col < col_end; col++) { + int src_alpha; + if (clip_scan) { + src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; + } else { + src_alpha = m_Alpha * cover_scan[col] / 255; + } + if (src_alpha) { + if (!index) { + *dest_scan1 &= ~(1 << (7 - (col + span_left) % 8)); + } else { + *dest_scan1 |= 1 << (7 - (col + span_left) % 8); } - if (Bpp == 3 && dest_extra_alpha_scan) { - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (m_bFullCover) { - if (clip_scan) { - src_alpha = m_Alpha * clip_scan[col] / 255; - } else { - src_alpha = m_Alpha; - } - } else { - if (clip_scan) { - src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; - } else { - src_alpha = m_Alpha * cover_scan[col] / 255; - } - } - if (src_alpha) { - if (src_alpha == 255) { - *dest_scan++ = (uint8_t)m_Blue; - *dest_scan++ = (uint8_t)m_Green; - *dest_scan++ = (uint8_t)m_Red; - *dest_extra_alpha_scan++ = (uint8_t)m_Alpha; - continue; - } else { - uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha - - (*dest_extra_alpha_scan) * src_alpha / 255; - *dest_extra_alpha_scan++ = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); - dest_scan ++; - continue; - } - } - dest_extra_alpha_scan++; - dest_scan += Bpp; - } + } + dest_scan1 = dest_scan + (span_left % 8 + col - col_start + 1) / 8; + } + } + void CompositeSpanGray(uint8_t* dest_scan, + int Bpp, + int span_left, + int span_len, + uint8_t* cover_scan, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan) { + ASSERT(!m_bRgbByteOrder); + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = (span_left + span_len) < clip_right + ? span_len + : (clip_right - span_left); + dest_scan += col_start; + if (dest_extra_alpha_scan) { + for (int col = col_start; col < col_end; col++) { + int src_alpha; + if (m_bFullCover) { + if (clip_scan) { + src_alpha = m_Alpha * clip_scan[col] / 255; + } else { + src_alpha = m_Alpha; + } } else { - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (m_bFullCover) { - if (clip_scan) { - src_alpha = m_Alpha * clip_scan[col] / 255; - } else { - src_alpha = m_Alpha; - } - } else { - if (clip_scan) { - src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; - } else { - src_alpha = m_Alpha * cover_scan[col] / 255; - } - } - if (src_alpha) { - if (src_alpha == 255) { - if (Bpp == 4) { - *(FX_DWORD*)dest_scan = m_Color; - } else if (Bpp == 3) { - *dest_scan++ = m_Blue; - *dest_scan++ = m_Green; - *dest_scan++ = m_Red; - continue; - } - } else { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha); - dest_scan += Bpp - 2; - continue; - } - } - dest_scan += Bpp; - } + if (clip_scan) { + src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; + } else { + src_alpha = m_Alpha * cover_scan[col] / 255; + } } - } - void CompositeSpanCMYK(uint8_t* dest_scan, int Bpp, - int span_left, int span_len, uint8_t* cover_scan, - int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan) - { - ASSERT(!m_bRgbByteOrder); - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - dest_scan += col_start * 4; - if (dest_extra_alpha_scan) { - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (m_bFullCover) { - if (clip_scan) { - src_alpha = m_Alpha * clip_scan[col] / 255; - } else { - src_alpha = m_Alpha; - } - } else { - if (clip_scan) { - src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; - } else { - src_alpha = m_Alpha * cover_scan[col] / 255; - } - } - if (src_alpha) { - if (src_alpha == 255) { - *(FX_CMYK*)dest_scan = m_Color; - *dest_extra_alpha_scan = (uint8_t)m_Alpha; - } else { - uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha - - (*dest_extra_alpha_scan) * src_alpha / 255; - *dest_extra_alpha_scan++ = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, alpha_ratio); - dest_scan ++; - continue; - } - } - dest_extra_alpha_scan++; - dest_scan += 4; - } + if (src_alpha) { + if (src_alpha == 255) { + *dest_scan = m_Gray; + *dest_extra_alpha_scan = m_Alpha; + } else { + uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha - + (*dest_extra_alpha_scan) * src_alpha / 255; + *dest_extra_alpha_scan++ = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, alpha_ratio); + dest_scan++; + continue; + } + } + dest_extra_alpha_scan++; + dest_scan++; + } + } else { + for (int col = col_start; col < col_end; col++) { + int src_alpha; + if (clip_scan) { + src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; } else { - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (clip_scan) { - src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; - } else { - src_alpha = m_Alpha * cover_scan[col] / 255; - } - if (src_alpha) { - if (src_alpha == 255) { - *(FX_CMYK*)dest_scan = m_Color; - } else { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, src_alpha); - dest_scan ++; - continue; - } - } - dest_scan += 4; - } + src_alpha = m_Alpha * cover_scan[col] / 255; } - } - template void render(const Scanline& sl) - { - if (m_pOriDevice == NULL && composite_span == NULL) { - return; + if (src_alpha) { + if (src_alpha == 255) { + *dest_scan = m_Gray; + } else { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, src_alpha); + } + } + dest_scan++; + } + } + } + void CompositeSpanARGB(uint8_t* dest_scan, + int Bpp, + int span_left, + int span_len, + uint8_t* cover_scan, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan) { + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = (span_left + span_len) < clip_right + ? span_len + : (clip_right - span_left); + dest_scan += col_start * Bpp; + if (m_bRgbByteOrder) { + for (int col = col_start; col < col_end; col++) { + int src_alpha; + if (m_bFullCover) { + if (clip_scan) { + src_alpha = m_Alpha * clip_scan[col] / 255; + } else { + src_alpha = m_Alpha; + } + } else { + if (clip_scan) { + src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; + } else { + src_alpha = m_Alpha * cover_scan[col] / 255; + } } - int y = sl.y(); - if (y < m_ClipBox.top || y >= m_ClipBox.bottom) { - return; + if (src_alpha) { + if (src_alpha == 255) { + *(FX_DWORD*)dest_scan = m_Color; + } else { + uint8_t dest_alpha = + dest_scan[3] + src_alpha - dest_scan[3] * src_alpha / 255; + dest_scan[3] = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); + dest_scan += 2; + continue; + } } - uint8_t* dest_scan = m_pDevice->GetBuffer() + m_pDevice->GetPitch() * y; - uint8_t* dest_scan_extra_alpha = NULL; - CFX_DIBitmap* pAlphaMask = m_pDevice->m_pAlphaMask; - if (pAlphaMask) { - dest_scan_extra_alpha = pAlphaMask->GetBuffer() + pAlphaMask->GetPitch() * y; + dest_scan += 4; + } + return; + } + for (int col = col_start; col < col_end; col++) { + int src_alpha; + if (m_bFullCover) { + if (clip_scan) { + src_alpha = m_Alpha * clip_scan[col] / 255; + } else { + src_alpha = m_Alpha; } - uint8_t* ori_scan = NULL; - if (m_pOriDevice) { - ori_scan = m_pOriDevice->GetBuffer() + m_pOriDevice->GetPitch() * y; + } else { + if (clip_scan) { + src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; + } else { + src_alpha = m_Alpha * cover_scan[col] / 255; } - int Bpp = m_pDevice->GetBPP() / 8; - FX_BOOL bDestAlpha = m_pDevice->HasAlpha() || m_pDevice->IsAlphaMask(); - unsigned num_spans = sl.num_spans(); - typename Scanline::const_iterator span = sl.begin(); - while (1) { - int x = span->x; - ASSERT(span->len > 0); - uint8_t* dest_pos = NULL; - uint8_t* dest_extra_alpha_pos = NULL; - uint8_t* ori_pos = NULL; - if (Bpp) { - ori_pos = ori_scan ? ori_scan + x * Bpp : NULL; - dest_pos = dest_scan + x * Bpp; - dest_extra_alpha_pos = dest_scan_extra_alpha ? dest_scan_extra_alpha + x : NULL; - } else { - dest_pos = dest_scan + x / 8; - ori_pos = ori_scan ? ori_scan + x / 8 : NULL; - } - uint8_t* clip_pos = NULL; - if (m_pClipMask) { - clip_pos = m_pClipMask->GetBuffer() + (y - m_ClipBox.top) * m_pClipMask->GetPitch() + x - m_ClipBox.left; - } - if (ori_pos) { - CompositeSpan(dest_pos, ori_pos, Bpp, bDestAlpha, x, span->len, span->covers, m_ClipBox.left, m_ClipBox.right, clip_pos); - } else { - (this->*composite_span)(dest_pos, Bpp, x, span->len, span->covers, m_ClipBox.left, m_ClipBox.right, clip_pos, dest_extra_alpha_pos); - } - if(--num_spans == 0) { - break; + } + if (src_alpha) { + if (src_alpha == 255) { + *(FX_DWORD*)dest_scan = m_Color; + } else { + if (dest_scan[3] == 0) { + dest_scan[3] = src_alpha; + *dest_scan++ = m_Blue; + *dest_scan++ = m_Green; + *dest_scan = m_Red; + dest_scan += 2; + continue; + } + uint8_t dest_alpha = + dest_scan[3] + src_alpha - dest_scan[3] * src_alpha / 255; + dest_scan[3] = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); + dest_scan += 2; + continue; + } + } + dest_scan += Bpp; + } + } + void CompositeSpanRGB(uint8_t* dest_scan, + int Bpp, + int span_left, + int span_len, + uint8_t* cover_scan, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan) { + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = (span_left + span_len) < clip_right + ? span_len + : (clip_right - span_left); + dest_scan += col_start * Bpp; + if (m_bRgbByteOrder) { + for (int col = col_start; col < col_end; col++) { + int src_alpha; + if (clip_scan) { + src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; + } else { + src_alpha = m_Alpha * cover_scan[col] / 255; + } + if (src_alpha) { + if (src_alpha == 255) { + if (Bpp == 4) { + *(FX_DWORD*)dest_scan = m_Color; + } else if (Bpp == 3) { + *dest_scan++ = m_Red; + *dest_scan++ = m_Green; + *dest_scan++ = m_Blue; + continue; } - ++span; + } else { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha); + dest_scan += Bpp - 2; + continue; + } } - } - - FX_BOOL Init(CFX_DIBitmap* pDevice, CFX_DIBitmap* pOriDevice, const CFX_ClipRgn* pClipRgn, FX_DWORD color, FX_BOOL bFullCover, FX_BOOL bRgbByteOrder, - int alpha_flag = 0, void* pIccTransform = NULL) - { - m_pDevice = pDevice; - m_pClipRgn = pClipRgn; - composite_span = NULL; - m_bRgbByteOrder = bRgbByteOrder; - m_pOriDevice = pOriDevice; - if (m_pClipRgn) { - m_ClipBox = m_pClipRgn->GetBox(); + dest_scan += Bpp; + } + return; + } + if (Bpp == 3 && dest_extra_alpha_scan) { + for (int col = col_start; col < col_end; col++) { + int src_alpha; + if (m_bFullCover) { + if (clip_scan) { + src_alpha = m_Alpha * clip_scan[col] / 255; + } else { + src_alpha = m_Alpha; + } } else { - m_ClipBox.left = m_ClipBox.top = 0; - m_ClipBox.right = m_pDevice->GetWidth(); - m_ClipBox.bottom = m_pDevice->GetHeight(); + if (clip_scan) { + src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; + } else { + src_alpha = m_Alpha * cover_scan[col] / 255; + } } - m_pClipMask = NULL; - if (m_pClipRgn && m_pClipRgn->GetType() == CFX_ClipRgn::MaskF) { - m_pClipMask = m_pClipRgn->GetMask(); + if (src_alpha) { + if (src_alpha == 255) { + *dest_scan++ = (uint8_t)m_Blue; + *dest_scan++ = (uint8_t)m_Green; + *dest_scan++ = (uint8_t)m_Red; + *dest_extra_alpha_scan++ = (uint8_t)m_Alpha; + continue; + } else { + uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha - + (*dest_extra_alpha_scan) * src_alpha / 255; + *dest_extra_alpha_scan++ = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); + dest_scan++; + continue; + } } - m_bFullCover = bFullCover; - FX_BOOL bObjectCMYK = FXGETFLAG_COLORTYPE(alpha_flag); - FX_BOOL bDeviceCMYK = pDevice->IsCmykImage(); - m_Alpha = bObjectCMYK ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(color); - ICodec_IccModule* pIccModule = NULL; - if (!CFX_GEModule::Get()->GetCodecModule() || !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) { - pIccTransform = NULL; + dest_extra_alpha_scan++; + dest_scan += Bpp; + } + } else { + for (int col = col_start; col < col_end; col++) { + int src_alpha; + if (m_bFullCover) { + if (clip_scan) { + src_alpha = m_Alpha * clip_scan[col] / 255; + } else { + src_alpha = m_Alpha; + } } else { - pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + if (clip_scan) { + src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; + } else { + src_alpha = m_Alpha * cover_scan[col] / 255; + } } - if (m_pDevice->GetBPP() == 8) { - ASSERT(!m_bRgbByteOrder); - composite_span = &CFX_Renderer::CompositeSpanGray; - if (m_pDevice->IsAlphaMask()) { - m_Gray = 255; - } else { - if (pIccTransform) { - uint8_t gray; - color = bObjectCMYK ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); - pIccModule->TranslateScanline(pIccTransform, &gray, (const uint8_t*)&color, 1); - m_Gray = gray; - } else { - if (bObjectCMYK) { - uint8_t r, g, b; - AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), FXSYS_GetYValue(color), FXSYS_GetKValue(color), - r, g, b); - m_Gray = FXRGB2GRAY(r, g, b); - } else { - m_Gray = FXRGB2GRAY(FXARGB_R(color), FXARGB_G(color), FXARGB_B(color)); - } - } + if (src_alpha) { + if (src_alpha == 255) { + if (Bpp == 4) { + *(FX_DWORD*)dest_scan = m_Color; + } else if (Bpp == 3) { + *dest_scan++ = m_Blue; + *dest_scan++ = m_Green; + *dest_scan++ = m_Red; + continue; } - return TRUE; + } else { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha); + dest_scan += Bpp - 2; + continue; + } } - if (bDeviceCMYK) { - ASSERT(!m_bRgbByteOrder); - composite_span = &CFX_Renderer::CompositeSpanCMYK; - if (bObjectCMYK) { - m_Color = FXCMYK_TODIB(color); - if (pIccTransform) { - pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&m_Color, (const uint8_t*)&m_Color, 1); - } - } else { - if (!pIccTransform) { - return FALSE; - } - color = FXARGB_TODIB(color); - pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&m_Color, (const uint8_t*)&color, 1); - } - m_Red = ((uint8_t*)&m_Color)[0]; - m_Green = ((uint8_t*)&m_Color)[1]; - m_Blue = ((uint8_t*)&m_Color)[2]; - m_Gray = ((uint8_t*)&m_Color)[3]; + dest_scan += Bpp; + } + } + } + void CompositeSpanCMYK(uint8_t* dest_scan, + int Bpp, + int span_left, + int span_len, + uint8_t* cover_scan, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan) { + ASSERT(!m_bRgbByteOrder); + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = (span_left + span_len) < clip_right + ? span_len + : (clip_right - span_left); + dest_scan += col_start * 4; + if (dest_extra_alpha_scan) { + for (int col = col_start; col < col_end; col++) { + int src_alpha; + if (m_bFullCover) { + if (clip_scan) { + src_alpha = m_Alpha * clip_scan[col] / 255; + } else { + src_alpha = m_Alpha; + } } else { - composite_span = (pDevice->GetFormat() == FXDIB_Argb) ? &CFX_Renderer::CompositeSpanARGB : &CFX_Renderer::CompositeSpanRGB; - if (pIccTransform) { - color = bObjectCMYK ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); - pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&m_Color, (const uint8_t*)&color, 1); - ((uint8_t*)&m_Color)[3] = m_Alpha; - m_Red = ((uint8_t*)&m_Color)[2]; - m_Green = ((uint8_t*)&m_Color)[1]; - m_Blue = ((uint8_t*)&m_Color)[0]; - if (m_bRgbByteOrder) { - m_Color = FXARGB_TODIB(m_Color); - m_Color = FXARGB_TOBGRORDERDIB(m_Color); - } - } else { - if (bObjectCMYK) { - uint8_t r, g, b; - AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), FXSYS_GetYValue(color), FXSYS_GetKValue(color), - r, g, b); - m_Color = FXARGB_MAKE(m_Alpha, r, g, b); - if (m_bRgbByteOrder) { - m_Color = FXARGB_TOBGRORDERDIB(m_Color); - } else { - m_Color = FXARGB_TODIB(m_Color); - } - m_Red = r; - m_Green = g; - m_Blue = b; - } else { - if (m_bRgbByteOrder) { - m_Color = FXARGB_TOBGRORDERDIB(color); - } else { - m_Color = FXARGB_TODIB(color); - } - ArgbDecode(color, m_Alpha, m_Red, m_Green, m_Blue); - } - } + if (clip_scan) { + src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; + } else { + src_alpha = m_Alpha * cover_scan[col] / 255; + } } - if (m_pDevice->GetBPP() == 1) { - composite_span = &CFX_Renderer::CompositeSpan1bpp; + if (src_alpha) { + if (src_alpha == 255) { + *(FX_CMYK*)dest_scan = m_Color; + *dest_extra_alpha_scan = (uint8_t)m_Alpha; + } else { + uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha - + (*dest_extra_alpha_scan) * src_alpha / 255; + *dest_extra_alpha_scan++ = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, alpha_ratio); + dest_scan++; + continue; + } } - return TRUE; + dest_extra_alpha_scan++; + dest_scan += 4; + } + } else { + for (int col = col_start; col < col_end; col++) { + int src_alpha; + if (clip_scan) { + src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255; + } else { + src_alpha = m_Alpha * cover_scan[col] / 255; + } + if (src_alpha) { + if (src_alpha == 255) { + *(FX_CMYK*)dest_scan = m_Color; + } else { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, src_alpha); + dest_scan++; + continue; + } + } + dest_scan += 4; + } + } + } + template + void render(const Scanline& sl) { + if (m_pOriDevice == NULL && composite_span == NULL) { + return; + } + int y = sl.y(); + if (y < m_ClipBox.top || y >= m_ClipBox.bottom) { + return; + } + uint8_t* dest_scan = m_pDevice->GetBuffer() + m_pDevice->GetPitch() * y; + uint8_t* dest_scan_extra_alpha = NULL; + CFX_DIBitmap* pAlphaMask = m_pDevice->m_pAlphaMask; + if (pAlphaMask) { + dest_scan_extra_alpha = + pAlphaMask->GetBuffer() + pAlphaMask->GetPitch() * y; + } + uint8_t* ori_scan = NULL; + if (m_pOriDevice) { + ori_scan = m_pOriDevice->GetBuffer() + m_pOriDevice->GetPitch() * y; + } + int Bpp = m_pDevice->GetBPP() / 8; + FX_BOOL bDestAlpha = m_pDevice->HasAlpha() || m_pDevice->IsAlphaMask(); + unsigned num_spans = sl.num_spans(); + typename Scanline::const_iterator span = sl.begin(); + while (1) { + int x = span->x; + ASSERT(span->len > 0); + uint8_t* dest_pos = NULL; + uint8_t* dest_extra_alpha_pos = NULL; + uint8_t* ori_pos = NULL; + if (Bpp) { + ori_pos = ori_scan ? ori_scan + x * Bpp : NULL; + dest_pos = dest_scan + x * Bpp; + dest_extra_alpha_pos = + dest_scan_extra_alpha ? dest_scan_extra_alpha + x : NULL; + } else { + dest_pos = dest_scan + x / 8; + ori_pos = ori_scan ? ori_scan + x / 8 : NULL; + } + uint8_t* clip_pos = NULL; + if (m_pClipMask) { + clip_pos = m_pClipMask->GetBuffer() + + (y - m_ClipBox.top) * m_pClipMask->GetPitch() + x - + m_ClipBox.left; + } + if (ori_pos) { + CompositeSpan(dest_pos, ori_pos, Bpp, bDestAlpha, x, span->len, + span->covers, m_ClipBox.left, m_ClipBox.right, clip_pos); + } else { + (this->*composite_span)(dest_pos, Bpp, x, span->len, span->covers, + m_ClipBox.left, m_ClipBox.right, clip_pos, + dest_extra_alpha_pos); + } + if (--num_spans == 0) { + break; + } + ++span; + } + } + + FX_BOOL Init(CFX_DIBitmap* pDevice, + CFX_DIBitmap* pOriDevice, + const CFX_ClipRgn* pClipRgn, + FX_DWORD color, + FX_BOOL bFullCover, + FX_BOOL bRgbByteOrder, + int alpha_flag = 0, + void* pIccTransform = NULL) { + m_pDevice = pDevice; + m_pClipRgn = pClipRgn; + composite_span = NULL; + m_bRgbByteOrder = bRgbByteOrder; + m_pOriDevice = pOriDevice; + if (m_pClipRgn) { + m_ClipBox = m_pClipRgn->GetBox(); + } else { + m_ClipBox.left = m_ClipBox.top = 0; + m_ClipBox.right = m_pDevice->GetWidth(); + m_ClipBox.bottom = m_pDevice->GetHeight(); + } + m_pClipMask = NULL; + if (m_pClipRgn && m_pClipRgn->GetType() == CFX_ClipRgn::MaskF) { + m_pClipMask = m_pClipRgn->GetMask(); + } + m_bFullCover = bFullCover; + FX_BOOL bObjectCMYK = FXGETFLAG_COLORTYPE(alpha_flag); + FX_BOOL bDeviceCMYK = pDevice->IsCmykImage(); + m_Alpha = bObjectCMYK ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(color); + ICodec_IccModule* pIccModule = NULL; + if (!CFX_GEModule::Get()->GetCodecModule() || + !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) { + pIccTransform = NULL; + } else { + pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + } + if (m_pDevice->GetBPP() == 8) { + ASSERT(!m_bRgbByteOrder); + composite_span = &CFX_Renderer::CompositeSpanGray; + if (m_pDevice->IsAlphaMask()) { + m_Gray = 255; + } else { + if (pIccTransform) { + uint8_t gray; + color = bObjectCMYK ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); + pIccModule->TranslateScanline(pIccTransform, &gray, + (const uint8_t*)&color, 1); + m_Gray = gray; + } else { + if (bObjectCMYK) { + uint8_t r, g, b; + AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), + FXSYS_GetYValue(color), FXSYS_GetKValue(color), + r, g, b); + m_Gray = FXRGB2GRAY(r, g, b); + } else { + m_Gray = + FXRGB2GRAY(FXARGB_R(color), FXARGB_G(color), FXARGB_B(color)); + } + } + } + return TRUE; + } + if (bDeviceCMYK) { + ASSERT(!m_bRgbByteOrder); + composite_span = &CFX_Renderer::CompositeSpanCMYK; + if (bObjectCMYK) { + m_Color = FXCMYK_TODIB(color); + if (pIccTransform) { + pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&m_Color, + (const uint8_t*)&m_Color, 1); + } + } else { + if (!pIccTransform) { + return FALSE; + } + color = FXARGB_TODIB(color); + pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&m_Color, + (const uint8_t*)&color, 1); + } + m_Red = ((uint8_t*)&m_Color)[0]; + m_Green = ((uint8_t*)&m_Color)[1]; + m_Blue = ((uint8_t*)&m_Color)[2]; + m_Gray = ((uint8_t*)&m_Color)[3]; + } else { + composite_span = (pDevice->GetFormat() == FXDIB_Argb) + ? &CFX_Renderer::CompositeSpanARGB + : &CFX_Renderer::CompositeSpanRGB; + if (pIccTransform) { + color = bObjectCMYK ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); + pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&m_Color, + (const uint8_t*)&color, 1); + ((uint8_t*)&m_Color)[3] = m_Alpha; + m_Red = ((uint8_t*)&m_Color)[2]; + m_Green = ((uint8_t*)&m_Color)[1]; + m_Blue = ((uint8_t*)&m_Color)[0]; + if (m_bRgbByteOrder) { + m_Color = FXARGB_TODIB(m_Color); + m_Color = FXARGB_TOBGRORDERDIB(m_Color); + } + } else { + if (bObjectCMYK) { + uint8_t r, g, b; + AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), + FXSYS_GetYValue(color), FXSYS_GetKValue(color), r, + g, b); + m_Color = FXARGB_MAKE(m_Alpha, r, g, b); + if (m_bRgbByteOrder) { + m_Color = FXARGB_TOBGRORDERDIB(m_Color); + } else { + m_Color = FXARGB_TODIB(m_Color); + } + m_Red = r; + m_Green = g; + m_Blue = b; + } else { + if (m_bRgbByteOrder) { + m_Color = FXARGB_TOBGRORDERDIB(color); + } else { + m_Color = FXARGB_TODIB(color); + } + ArgbDecode(color, m_Alpha, m_Red, m_Green, m_Blue); + } + } } -}; -FX_BOOL CFX_AggDeviceDriver::RenderRasterizer(agg::rasterizer_scanline_aa& rasterizer, FX_DWORD color, FX_BOOL bFullCover, FX_BOOL bGroupKnockout, - int alpha_flag, void* pIccTransform) -{ - CFX_DIBitmap* pt = bGroupKnockout ? m_pOriDevice : NULL; - CFX_Renderer render; - if (!render.Init(m_pBitmap, pt, m_pClipRgn, color, bFullCover, m_bRgbByteOrder, alpha_flag, pIccTransform)) { - return FALSE; + if (m_pDevice->GetBPP() == 1) { + composite_span = &CFX_Renderer::CompositeSpan1bpp; } - agg::scanline_u8 scanline; - agg::render_scanlines(rasterizer, scanline, render, (m_FillFlags & FXFILL_NOPATHSMOOTH) != 0); return TRUE; + } +}; +FX_BOOL CFX_AggDeviceDriver::RenderRasterizer( + agg::rasterizer_scanline_aa& rasterizer, + FX_DWORD color, + FX_BOOL bFullCover, + FX_BOOL bGroupKnockout, + int alpha_flag, + void* pIccTransform) { + CFX_DIBitmap* pt = bGroupKnockout ? m_pOriDevice : NULL; + CFX_Renderer render; + if (!render.Init(m_pBitmap, pt, m_pClipRgn, color, bFullCover, + m_bRgbByteOrder, alpha_flag, pIccTransform)) { + return FALSE; + } + agg::scanline_u8 scanline; + agg::render_scanlines(rasterizer, scanline, render, + (m_FillFlags & FXFILL_NOPATHSMOOTH) != 0); + return TRUE; } -FX_BOOL CFX_AggDeviceDriver::DrawPath(const CFX_PathData* pPathData, +FX_BOOL CFX_AggDeviceDriver::DrawPath(const CFX_PathData* pPathData, const CFX_AffineMatrix* pObject2Device, const CFX_GraphStateData* pGraphState, FX_DWORD fill_color, @@ -1123,483 +1209,586 @@ FX_BOOL CFX_AggDeviceDriver::DrawPath(const CFX_PathData* pPathData, int fill_mode, int alpha_flag, void* pIccTransform, - int blend_type - ) -{ - if (blend_type != FXDIB_BLEND_NORMAL) { + int blend_type) { + if (blend_type != FXDIB_BLEND_NORMAL) { + return FALSE; + } + if (GetBuffer() == NULL) { + return TRUE; + } + m_FillFlags = fill_mode; + if ((fill_mode & 3) && fill_color) { + CAgg_PathData path_data; + path_data.BuildPath(pPathData, pObject2Device); + agg::rasterizer_scanline_aa rasterizer; + rasterizer.clip_box(0.0f, 0.0f, (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_WIDTH)), + (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_HEIGHT))); + rasterizer.add_path(path_data.m_PathData); + rasterizer.filling_rule((fill_mode & 3) == FXFILL_WINDING + ? agg::fill_non_zero + : agg::fill_even_odd); + if (!RenderRasterizer(rasterizer, fill_color, fill_mode & FXFILL_FULLCOVER, + FALSE, alpha_flag, pIccTransform)) { + return FALSE; + } + } + int stroke_alpha = FXGETFLAG_COLORTYPE(alpha_flag) + ? FXGETFLAG_ALPHA_STROKE(alpha_flag) + : FXARGB_A(stroke_color); + if (pGraphState && stroke_alpha) { + if (fill_mode & FX_ZEROAREA_FILL) { + CAgg_PathData path_data; + path_data.BuildPath(pPathData, pObject2Device); + agg::rasterizer_scanline_aa rasterizer; + rasterizer.clip_box(0.0f, 0.0f, + (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_WIDTH)), + (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_HEIGHT))); + RasterizeStroke(rasterizer, path_data.m_PathData, NULL, pGraphState, 1, + FALSE, fill_mode & FX_STROKE_TEXT_MODE); + int fill_flag = FXGETFLAG_COLORTYPE(alpha_flag) << 8 | + FXGETFLAG_ALPHA_STROKE(alpha_flag); + if (!RenderRasterizer(rasterizer, stroke_color, + fill_mode & FXFILL_FULLCOVER, m_bGroupKnockout, + fill_flag, pIccTransform)) { return FALSE; + } + return TRUE; } - if (GetBuffer() == NULL) { - return TRUE; - } - m_FillFlags = fill_mode; - if ((fill_mode & 3) && fill_color) { - CAgg_PathData path_data; - path_data.BuildPath(pPathData, pObject2Device); - agg::rasterizer_scanline_aa rasterizer; - rasterizer.clip_box(0.0f, 0.0f, (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_WIDTH)), (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_HEIGHT))); - rasterizer.add_path(path_data.m_PathData); - rasterizer.filling_rule((fill_mode & 3) == FXFILL_WINDING ? agg::fill_non_zero : agg::fill_even_odd); - if (!RenderRasterizer(rasterizer, fill_color, fill_mode & FXFILL_FULLCOVER, FALSE, alpha_flag, pIccTransform)) { - return FALSE; - } + CFX_AffineMatrix matrix1, matrix2; + if (pObject2Device) { + matrix1.a = + FX_MAX(FXSYS_fabs(pObject2Device->a), FXSYS_fabs(pObject2Device->b)); + matrix1.d = matrix1.a; + matrix2.Set(pObject2Device->a / matrix1.a, pObject2Device->b / matrix1.a, + pObject2Device->c / matrix1.d, pObject2Device->d / matrix1.d, + 0, 0); + CFX_AffineMatrix mtRervese; + mtRervese.SetReverse(matrix2); + matrix1 = *pObject2Device; + matrix1.Concat(mtRervese); } - int stroke_alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_STROKE(alpha_flag) : FXARGB_A(stroke_color); - if (pGraphState && stroke_alpha) { - if (fill_mode & FX_ZEROAREA_FILL) { - CAgg_PathData path_data; - path_data.BuildPath(pPathData, pObject2Device); - agg::rasterizer_scanline_aa rasterizer; - rasterizer.clip_box(0.0f, 0.0f, (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_WIDTH)), (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_HEIGHT))); - RasterizeStroke(rasterizer, path_data.m_PathData, NULL, pGraphState, 1, FALSE, fill_mode & FX_STROKE_TEXT_MODE); - int fill_flag = FXGETFLAG_COLORTYPE(alpha_flag) << 8 | FXGETFLAG_ALPHA_STROKE(alpha_flag); - if (!RenderRasterizer(rasterizer, stroke_color, fill_mode & FXFILL_FULLCOVER, m_bGroupKnockout, fill_flag, pIccTransform)) { - return FALSE; - } - return TRUE; + CAgg_PathData path_data; + path_data.BuildPath(pPathData, &matrix1); + agg::rasterizer_scanline_aa rasterizer; + rasterizer.clip_box(0.0f, 0.0f, (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_WIDTH)), + (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_HEIGHT))); + RasterizeStroke(rasterizer, path_data.m_PathData, &matrix2, pGraphState, + matrix1.a, FALSE, fill_mode & FX_STROKE_TEXT_MODE); + int fill_flag = FXGETFLAG_COLORTYPE(alpha_flag) << 8 | + FXGETFLAG_ALPHA_STROKE(alpha_flag); + if (!RenderRasterizer(rasterizer, stroke_color, + fill_mode & FXFILL_FULLCOVER, m_bGroupKnockout, + fill_flag, pIccTransform)) { + return FALSE; + } + } + return TRUE; +} +void RgbByteOrderSetPixel(CFX_DIBitmap* pBitmap, int x, int y, FX_DWORD argb) { + if (x < 0 || x >= pBitmap->GetWidth() || y < 0 || y >= pBitmap->GetHeight()) { + return; + } + uint8_t* pos = (uint8_t*)pBitmap->GetBuffer() + y * pBitmap->GetPitch() + + x * pBitmap->GetBPP() / 8; + if (pBitmap->GetFormat() == FXDIB_Argb) { + FXARGB_SETRGBORDERDIB(pos, ArgbGamma(argb)); + } else { + int alpha = FXARGB_A(argb); + pos[0] = (FXARGB_R(argb) * alpha + pos[0] * (255 - alpha)) / 255; + pos[1] = (FXARGB_G(argb) * alpha + pos[1] * (255 - alpha)) / 255; + pos[2] = (FXARGB_B(argb) * alpha + pos[2] * (255 - alpha)) / 255; + } +} +void RgbByteOrderCompositeRect(CFX_DIBitmap* pBitmap, + int left, + int top, + int width, + int height, + FX_ARGB argb) { + int src_alpha = FXARGB_A(argb); + if (src_alpha == 0) { + return; + } + FX_RECT rect(left, top, left + width, top + height); + rect.Intersect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight()); + width = rect.Width(); + int src_r = FXARGB_R(argb), src_g = FXARGB_G(argb), src_b = FXARGB_B(argb); + int Bpp = pBitmap->GetBPP() / 8; + FX_BOOL bAlpha = pBitmap->HasAlpha(); + int dib_argb = FXARGB_TOBGRORDERDIB(argb); + uint8_t* pBuffer = pBitmap->GetBuffer(); + if (src_alpha == 255) { + for (int row = rect.top; row < rect.bottom; row++) { + uint8_t* dest_scan = + pBuffer + row * pBitmap->GetPitch() + rect.left * Bpp; + if (Bpp == 4) { + FX_DWORD* scan = (FX_DWORD*)dest_scan; + for (int col = 0; col < width; col++) { + *scan++ = dib_argb; } - CFX_AffineMatrix matrix1, matrix2; - if (pObject2Device) { - matrix1.a = FX_MAX(FXSYS_fabs(pObject2Device->a), FXSYS_fabs(pObject2Device->b)); - matrix1.d = matrix1.a; - matrix2.Set(pObject2Device->a / matrix1.a, pObject2Device->b / matrix1.a, - pObject2Device->c / matrix1.d, pObject2Device->d / matrix1.d, - 0, 0); - CFX_AffineMatrix mtRervese; - mtRervese.SetReverse(matrix2); - matrix1 = *pObject2Device; - matrix1.Concat(mtRervese); + } else { + for (int col = 0; col < width; col++) { + *dest_scan++ = src_r; + *dest_scan++ = src_g; + *dest_scan++ = src_b; } - CAgg_PathData path_data; - path_data.BuildPath(pPathData, &matrix1); - agg::rasterizer_scanline_aa rasterizer; - rasterizer.clip_box(0.0f, 0.0f, (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_WIDTH)), (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_HEIGHT))); - RasterizeStroke(rasterizer, path_data.m_PathData, &matrix2, pGraphState, matrix1.a, FALSE, fill_mode & FX_STROKE_TEXT_MODE); - int fill_flag = FXGETFLAG_COLORTYPE(alpha_flag) << 8 | FXGETFLAG_ALPHA_STROKE(alpha_flag); - if (!RenderRasterizer(rasterizer, stroke_color, fill_mode & FXFILL_FULLCOVER, m_bGroupKnockout, fill_flag, pIccTransform)) { - return FALSE; + } + } + return; + } + src_r = FX_GAMMA(src_r); + src_g = FX_GAMMA(src_g); + src_b = FX_GAMMA(src_b); + for (int row = rect.top; row < rect.bottom; row++) { + uint8_t* dest_scan = pBuffer + row * pBitmap->GetPitch() + rect.left * Bpp; + if (bAlpha) { + for (int col = 0; col < width; col++) { + uint8_t back_alpha = dest_scan[3]; + if (back_alpha == 0) { + FXARGB_SETRGBORDERDIB(dest_scan, + FXARGB_MAKE(src_alpha, src_r, src_g, src_b)); + dest_scan += 4; + continue; } - } - return TRUE; -} -void RgbByteOrderSetPixel(CFX_DIBitmap* pBitmap, int x, int y, FX_DWORD argb) -{ - if (x < 0 || x >= pBitmap->GetWidth() || y < 0 || y >= pBitmap->GetHeight()) { - return; - } - uint8_t* pos = (uint8_t*)pBitmap->GetBuffer() + y * pBitmap->GetPitch() + x * pBitmap->GetBPP() / 8; - if (pBitmap->GetFormat() == FXDIB_Argb) { - FXARGB_SETRGBORDERDIB(pos, ArgbGamma(argb)); + uint8_t dest_alpha = + back_alpha + src_alpha - back_alpha * src_alpha / 255; + dest_scan[3] = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio); + dest_scan += 2; + } } else { - int alpha = FXARGB_A(argb); - pos[0] = (FXARGB_R(argb) * alpha + pos[0] * (255 - alpha)) / 255; - pos[1] = (FXARGB_G(argb) * alpha + pos[1] * (255 - alpha)) / 255; - pos[2] = (FXARGB_B(argb) * alpha + pos[2] * (255 - alpha)) / 255; + for (int col = 0; col < width; col++) { + *dest_scan = FX_GAMMA_INVERSE( + FXDIB_ALPHA_MERGE(FX_GAMMA(*dest_scan), src_r, src_alpha)); + dest_scan++; + *dest_scan = FX_GAMMA_INVERSE( + FXDIB_ALPHA_MERGE(FX_GAMMA(*dest_scan), src_g, src_alpha)); + dest_scan++; + *dest_scan = FX_GAMMA_INVERSE( + FXDIB_ALPHA_MERGE(FX_GAMMA(*dest_scan), src_b, src_alpha)); + dest_scan++; + if (Bpp == 4) { + dest_scan++; + } + } } + } } -void RgbByteOrderCompositeRect(CFX_DIBitmap* pBitmap, int left, int top, int width, int height, FX_ARGB argb) -{ - int src_alpha = FXARGB_A(argb); - if (src_alpha == 0) { - return; - } - FX_RECT rect(left, top, left + width, top + height); - rect.Intersect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight()); - width = rect.Width(); - int src_r = FXARGB_R(argb), src_g = FXARGB_G(argb), src_b = FXARGB_B(argb); - int Bpp = pBitmap->GetBPP() / 8; - FX_BOOL bAlpha = pBitmap->HasAlpha(); - int dib_argb = FXARGB_TOBGRORDERDIB(argb); - uint8_t* pBuffer = pBitmap->GetBuffer(); - if (src_alpha == 255) { - for (int row = rect.top; row < rect.bottom; row ++) { - uint8_t* dest_scan = pBuffer + row * pBitmap->GetPitch() + rect.left * Bpp; - if (Bpp == 4) { - FX_DWORD* scan = (FX_DWORD*)dest_scan; - for (int col = 0; col < width; col ++) { - *scan ++ = dib_argb; - } - } else { - for (int col = 0; col < width; col ++) { - *dest_scan ++ = src_r; - *dest_scan ++ = src_g; - *dest_scan ++ = src_b; - } - } +void RgbByteOrderTransferBitmap(CFX_DIBitmap* pBitmap, + int dest_left, + int dest_top, + int width, + int height, + const CFX_DIBSource* pSrcBitmap, + int src_left, + int src_top) { + if (pBitmap == NULL) { + return; + } + pBitmap->GetOverlapRect(dest_left, dest_top, width, height, + pSrcBitmap->GetWidth(), pSrcBitmap->GetHeight(), + src_left, src_top, NULL); + if (width == 0 || height == 0) { + return; + } + int Bpp = pBitmap->GetBPP() / 8; + FXDIB_Format dest_format = pBitmap->GetFormat(); + FXDIB_Format src_format = pSrcBitmap->GetFormat(); + int pitch = pBitmap->GetPitch(); + uint8_t* buffer = pBitmap->GetBuffer(); + if (dest_format == src_format) { + for (int row = 0; row < height; row++) { + uint8_t* dest_scan = buffer + (dest_top + row) * pitch + dest_left * Bpp; + uint8_t* src_scan = + (uint8_t*)pSrcBitmap->GetScanline(src_top + row) + src_left * Bpp; + if (Bpp == 4) { + for (int col = 0; col < width; col++) { + FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_scan[3], src_scan[0], + src_scan[1], src_scan[2])); + dest_scan += 4; + src_scan += 4; } - return; - } - src_r = FX_GAMMA(src_r); - src_g = FX_GAMMA(src_g); - src_b = FX_GAMMA(src_b); - for (int row = rect.top; row < rect.bottom; row ++) { - uint8_t* dest_scan = pBuffer + row * pBitmap->GetPitch() + rect.left * Bpp; - if (bAlpha) { - for (int col = 0; col < width; col ++) { - uint8_t back_alpha = dest_scan[3]; - if (back_alpha == 0) { - FXARGB_SETRGBORDERDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b)); - dest_scan += 4; - continue; - } - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - dest_scan[3] = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio); - dest_scan++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio); - dest_scan++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio); - dest_scan += 2; - } - } else { - for (int col = 0; col < width; col ++) { - *dest_scan = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(*dest_scan), src_r, src_alpha)); - dest_scan++; - *dest_scan = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(*dest_scan), src_g, src_alpha)); - dest_scan++; - *dest_scan = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(*dest_scan), src_b, src_alpha)); - dest_scan++; - if (Bpp == 4) { - dest_scan++; - } - } + } else { + for (int col = 0; col < width; col++) { + *dest_scan++ = src_scan[2]; + *dest_scan++ = src_scan[1]; + *dest_scan++ = src_scan[0]; + src_scan += 3; } - } -} -void RgbByteOrderTransferBitmap(CFX_DIBitmap* pBitmap, int dest_left, int dest_top, int width, int height, - const CFX_DIBSource* pSrcBitmap, int src_left, int src_top) -{ - if (pBitmap == NULL) { - return; - } - pBitmap->GetOverlapRect(dest_left, dest_top, width, height, pSrcBitmap->GetWidth(), pSrcBitmap->GetHeight(), src_left, src_top, NULL); - if (width == 0 || height == 0) { - return; - } - int Bpp = pBitmap->GetBPP() / 8; - FXDIB_Format dest_format = pBitmap->GetFormat(); - FXDIB_Format src_format = pSrcBitmap->GetFormat(); - int pitch = pBitmap->GetPitch(); - uint8_t* buffer = pBitmap->GetBuffer(); - if (dest_format == src_format) { - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = buffer + (dest_top + row) * pitch + dest_left * Bpp; - uint8_t* src_scan = (uint8_t*)pSrcBitmap->GetScanline(src_top + row) + src_left * Bpp; - if (Bpp == 4) { - for (int col = 0; col < width; col ++) { - FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_scan[3], src_scan[0], src_scan[1], src_scan[2])); - dest_scan += 4; - src_scan += 4; - } - } else { - for (int col = 0; col < width; col ++) { - *dest_scan++ = src_scan[2]; - *dest_scan++ = src_scan[1]; - *dest_scan++ = src_scan[0]; - src_scan += 3; - } - } + } + } + return; + } + uint8_t* dest_buf = buffer + dest_top * pitch + dest_left * Bpp; + if (dest_format == FXDIB_Rgb) { + if (src_format == FXDIB_Rgb32) { + for (int row = 0; row < height; row++) { + uint8_t* dest_scan = dest_buf + row * pitch; + uint8_t* src_scan = + (uint8_t*)pSrcBitmap->GetScanline(src_top + row) + src_left * 4; + for (int col = 0; col < width; col++) { + *dest_scan++ = src_scan[2]; + *dest_scan++ = src_scan[1]; + *dest_scan++ = src_scan[0]; + src_scan += 4; } - return; - } - uint8_t* dest_buf = buffer + dest_top * pitch + dest_left * Bpp; - if (dest_format == FXDIB_Rgb) { - if (src_format == FXDIB_Rgb32) { - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = dest_buf + row * pitch; - uint8_t* src_scan = (uint8_t*)pSrcBitmap->GetScanline(src_top + row) + src_left * 4; - for (int col = 0; col < width; col ++) { - *dest_scan++ = src_scan[2]; - *dest_scan++ = src_scan[1]; - *dest_scan++ = src_scan[0]; - src_scan += 4; - } - } + } + } else { + ASSERT(FALSE); + } + } else if (dest_format == FXDIB_Argb || dest_format == FXDIB_Rgb32) { + if (src_format == FXDIB_Rgb) { + for (int row = 0; row < height; row++) { + uint8_t* dest_scan = (uint8_t*)(dest_buf + row * pitch); + uint8_t* src_scan = + (uint8_t*)pSrcBitmap->GetScanline(src_top + row) + src_left * 3; + if (src_format == FXDIB_Argb) { + for (int col = 0; col < width; col++) { + FXARGB_SETDIB(dest_scan, FXARGB_MAKE(0xff, FX_GAMMA(src_scan[0]), + FX_GAMMA(src_scan[1]), + FX_GAMMA(src_scan[2]))); + dest_scan += 4; + src_scan += 3; + } } else { - ASSERT(FALSE); + for (int col = 0; col < width; col++) { + FXARGB_SETDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[0], src_scan[1], + src_scan[2])); + dest_scan += 4; + src_scan += 3; + } } - } else if (dest_format == FXDIB_Argb || dest_format == FXDIB_Rgb32) { - if (src_format == FXDIB_Rgb) { - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = (uint8_t*)(dest_buf + row * pitch); - uint8_t* src_scan = (uint8_t*)pSrcBitmap->GetScanline(src_top + row) + src_left * 3; - if (src_format == FXDIB_Argb) { - for (int col = 0; col < width; col ++) { - FXARGB_SETDIB(dest_scan, FXARGB_MAKE(0xff, FX_GAMMA(src_scan[0]), FX_GAMMA(src_scan[1]), FX_GAMMA(src_scan[2]))); - dest_scan += 4; - src_scan += 3; - } - } else { - for (int col = 0; col < width; col ++) { - FXARGB_SETDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[0], src_scan[1], src_scan[2])); - dest_scan += 4; - src_scan += 3; - } - } - } - } else if (src_format == FXDIB_Rgb32) { - ASSERT(dest_format == FXDIB_Argb); - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = dest_buf + row * pitch; - uint8_t* src_scan = (uint8_t*)(pSrcBitmap->GetScanline(src_top + row) + src_left * 4); - for (int col = 0; col < width; col++) { - FXARGB_SETDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[0], src_scan[1], src_scan[2])); - src_scan += 4; - dest_scan += 4; - } - } + } + } else if (src_format == FXDIB_Rgb32) { + ASSERT(dest_format == FXDIB_Argb); + for (int row = 0; row < height; row++) { + uint8_t* dest_scan = dest_buf + row * pitch; + uint8_t* src_scan = + (uint8_t*)(pSrcBitmap->GetScanline(src_top + row) + src_left * 4); + for (int col = 0; col < width; col++) { + FXARGB_SETDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[0], src_scan[1], + src_scan[2])); + src_scan += 4; + dest_scan += 4; } - } else { - ASSERT(FALSE); + } } + } else { + ASSERT(FALSE); + } } -FX_ARGB _DefaultCMYK2ARGB(FX_CMYK cmyk, uint8_t alpha) -{ - uint8_t r, g, b; - AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk), FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk), - r, g, b); - return ArgbEncode(alpha, r, g, b); +FX_ARGB _DefaultCMYK2ARGB(FX_CMYK cmyk, uint8_t alpha) { + uint8_t r, g, b; + AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk), + FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk), r, g, b); + return ArgbEncode(alpha, r, g, b); } -FX_BOOL _DibSetPixel(CFX_DIBitmap* pDevice, int x, int y, FX_DWORD color, int alpha_flag, void* pIccTransform) -{ - FX_BOOL bObjCMYK = FXGETFLAG_COLORTYPE(alpha_flag); - int alpha = bObjCMYK ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(color); - if (pIccTransform) { - ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - color = bObjCMYK ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); - pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&color, (uint8_t*)&color, 1); - color = bObjCMYK ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); - if (!pDevice->IsCmykImage()) { - color = (color & 0xffffff) | (alpha << 24); - } +FX_BOOL _DibSetPixel(CFX_DIBitmap* pDevice, + int x, + int y, + FX_DWORD color, + int alpha_flag, + void* pIccTransform) { + FX_BOOL bObjCMYK = FXGETFLAG_COLORTYPE(alpha_flag); + int alpha = bObjCMYK ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(color); + if (pIccTransform) { + ICodec_IccModule* pIccModule = + CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + color = bObjCMYK ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); + pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&color, + (uint8_t*)&color, 1); + color = bObjCMYK ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); + if (!pDevice->IsCmykImage()) { + color = (color & 0xffffff) | (alpha << 24); + } + } else { + if (pDevice->IsCmykImage()) { + if (!bObjCMYK) { + return FALSE; + } } else { - if (pDevice->IsCmykImage()) { - if (!bObjCMYK) { - return FALSE; - } - } else { - if (bObjCMYK) { - color = _DefaultCMYK2ARGB(color, alpha); - } - } - } - pDevice->SetPixel(x, y, color); - if (pDevice->m_pAlphaMask) { - pDevice->m_pAlphaMask->SetPixel(x, y, alpha << 24); - } - return TRUE; + if (bObjCMYK) { + color = _DefaultCMYK2ARGB(color, alpha); + } + } + } + pDevice->SetPixel(x, y, color); + if (pDevice->m_pAlphaMask) { + pDevice->m_pAlphaMask->SetPixel(x, y, alpha << 24); + } + return TRUE; } -FX_BOOL CFX_AggDeviceDriver::SetPixel(int x, int y, FX_DWORD color, int alpha_flag, void* pIccTransform) -{ - if (m_pBitmap->GetBuffer() == NULL) { - return TRUE; - } - if (!CFX_GEModule::Get()->GetCodecModule() || !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) { - pIccTransform = NULL; - } - if (m_pClipRgn == NULL) { - if (m_bRgbByteOrder) { - RgbByteOrderSetPixel(m_pBitmap, x, y, color); - } else { - return _DibSetPixel(m_pBitmap, x, y, color, alpha_flag, pIccTransform); - } - } else if (m_pClipRgn->GetBox().Contains(x, y)) { - if (m_pClipRgn->GetType() == CFX_ClipRgn::RectI) { - if (m_bRgbByteOrder) { - RgbByteOrderSetPixel(m_pBitmap, x, y, color); - } else { - return _DibSetPixel(m_pBitmap, x, y, color, alpha_flag, pIccTransform); - } - } else if (m_pClipRgn->GetType() == CFX_ClipRgn::MaskF) { - const CFX_DIBitmap* pMask = m_pClipRgn->GetMask(); - FX_BOOL bCMYK = FXGETFLAG_COLORTYPE(alpha_flag); - int new_alpha = bCMYK ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(color); - new_alpha = new_alpha * pMask->GetScanline(y)[x] / 255; - if (m_bRgbByteOrder) { - RgbByteOrderSetPixel(m_pBitmap, x, y, (color & 0xffffff) | (new_alpha << 24)); - return TRUE; - } - if (bCMYK) { - FXSETFLAG_ALPHA_FILL(alpha_flag, new_alpha); - } else { - color = (color & 0xffffff) | (new_alpha << 24); - } - return _DibSetPixel(m_pBitmap, x, y, color, alpha_flag, pIccTransform); - } - } +FX_BOOL CFX_AggDeviceDriver::SetPixel(int x, + int y, + FX_DWORD color, + int alpha_flag, + void* pIccTransform) { + if (m_pBitmap->GetBuffer() == NULL) { return TRUE; -} -FX_BOOL CFX_AggDeviceDriver::FillRect(const FX_RECT* pRect, FX_DWORD fill_color, int alpha_flag, void* pIccTransform, int blend_type) -{ - if (blend_type != FXDIB_BLEND_NORMAL) { - return FALSE; - } - if (m_pBitmap->GetBuffer() == NULL) { - return TRUE; - } - FX_RECT clip_rect; - GetClipBox(&clip_rect); - FX_RECT draw_rect = clip_rect; - if (pRect) { - draw_rect.Intersect(*pRect); - } - if (draw_rect.IsEmpty()) { - return TRUE; - } - if (m_pClipRgn == NULL || m_pClipRgn->GetType() == CFX_ClipRgn::RectI) { - if (m_bRgbByteOrder) { - RgbByteOrderCompositeRect(m_pBitmap, draw_rect.left, draw_rect.top, draw_rect.Width(), draw_rect.Height(), fill_color); - } else { - m_pBitmap->CompositeRect(draw_rect.left, draw_rect.top, draw_rect.Width(), draw_rect.Height(), fill_color, alpha_flag, pIccTransform); - } + } + if (!CFX_GEModule::Get()->GetCodecModule() || + !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) { + pIccTransform = NULL; + } + if (m_pClipRgn == NULL) { + if (m_bRgbByteOrder) { + RgbByteOrderSetPixel(m_pBitmap, x, y, color); + } else { + return _DibSetPixel(m_pBitmap, x, y, color, alpha_flag, pIccTransform); + } + } else if (m_pClipRgn->GetBox().Contains(x, y)) { + if (m_pClipRgn->GetType() == CFX_ClipRgn::RectI) { + if (m_bRgbByteOrder) { + RgbByteOrderSetPixel(m_pBitmap, x, y, color); + } else { + return _DibSetPixel(m_pBitmap, x, y, color, alpha_flag, pIccTransform); + } + } else if (m_pClipRgn->GetType() == CFX_ClipRgn::MaskF) { + const CFX_DIBitmap* pMask = m_pClipRgn->GetMask(); + FX_BOOL bCMYK = FXGETFLAG_COLORTYPE(alpha_flag); + int new_alpha = + bCMYK ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(color); + new_alpha = new_alpha * pMask->GetScanline(y)[x] / 255; + if (m_bRgbByteOrder) { + RgbByteOrderSetPixel(m_pBitmap, x, y, + (color & 0xffffff) | (new_alpha << 24)); return TRUE; + } + if (bCMYK) { + FXSETFLAG_ALPHA_FILL(alpha_flag, new_alpha); + } else { + color = (color & 0xffffff) | (new_alpha << 24); + } + return _DibSetPixel(m_pBitmap, x, y, color, alpha_flag, pIccTransform); + } + } + return TRUE; +} +FX_BOOL CFX_AggDeviceDriver::FillRect(const FX_RECT* pRect, + FX_DWORD fill_color, + int alpha_flag, + void* pIccTransform, + int blend_type) { + if (blend_type != FXDIB_BLEND_NORMAL) { + return FALSE; + } + if (m_pBitmap->GetBuffer() == NULL) { + return TRUE; + } + FX_RECT clip_rect; + GetClipBox(&clip_rect); + FX_RECT draw_rect = clip_rect; + if (pRect) { + draw_rect.Intersect(*pRect); + } + if (draw_rect.IsEmpty()) { + return TRUE; + } + if (m_pClipRgn == NULL || m_pClipRgn->GetType() == CFX_ClipRgn::RectI) { + if (m_bRgbByteOrder) { + RgbByteOrderCompositeRect(m_pBitmap, draw_rect.left, draw_rect.top, + draw_rect.Width(), draw_rect.Height(), + fill_color); + } else { + m_pBitmap->CompositeRect(draw_rect.left, draw_rect.top, draw_rect.Width(), + draw_rect.Height(), fill_color, alpha_flag, + pIccTransform); } - m_pBitmap->CompositeMask(draw_rect.left, draw_rect.top, draw_rect.Width(), draw_rect.Height(), (const CFX_DIBitmap*)m_pClipRgn->GetMask(), - fill_color, draw_rect.left - clip_rect.left, draw_rect.top - clip_rect.top, FXDIB_BLEND_NORMAL, NULL, m_bRgbByteOrder, alpha_flag, pIccTransform); return TRUE; + } + m_pBitmap->CompositeMask( + draw_rect.left, draw_rect.top, draw_rect.Width(), draw_rect.Height(), + (const CFX_DIBitmap*)m_pClipRgn->GetMask(), fill_color, + draw_rect.left - clip_rect.left, draw_rect.top - clip_rect.top, + FXDIB_BLEND_NORMAL, NULL, m_bRgbByteOrder, alpha_flag, pIccTransform); + return TRUE; } -FX_BOOL CFX_AggDeviceDriver::GetClipBox(FX_RECT* pRect) -{ - if (m_pClipRgn == NULL) { - pRect->left = pRect->top = 0; - pRect->right = GetDeviceCaps(FXDC_PIXEL_WIDTH); - pRect->bottom = GetDeviceCaps(FXDC_PIXEL_HEIGHT); - return TRUE; - } - *pRect = m_pClipRgn->GetBox(); +FX_BOOL CFX_AggDeviceDriver::GetClipBox(FX_RECT* pRect) { + if (m_pClipRgn == NULL) { + pRect->left = pRect->top = 0; + pRect->right = GetDeviceCaps(FXDC_PIXEL_WIDTH); + pRect->bottom = GetDeviceCaps(FXDC_PIXEL_HEIGHT); return TRUE; + } + *pRect = m_pClipRgn->GetBox(); + return TRUE; } -FX_BOOL CFX_AggDeviceDriver::GetDIBits(CFX_DIBitmap* pBitmap, int left, int top, void* pIccTransform, FX_BOOL bDEdge) -{ - if (m_pBitmap->GetBuffer() == NULL) { - return TRUE; - } - if (bDEdge) { - if (m_bRgbByteOrder) { - RgbByteOrderTransferBitmap(pBitmap, 0, 0, pBitmap->GetWidth(), pBitmap->GetHeight(), m_pBitmap, left, top); - } else { - return pBitmap->TransferBitmap(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight(), m_pBitmap, left, top, pIccTransform); - } - return TRUE; - } - FX_RECT rect(left, top, left + pBitmap->GetWidth(), top + pBitmap->GetHeight()); - CFX_DIBitmap *pBack = NULL; - if (m_pOriDevice) { - pBack = m_pOriDevice->Clone(&rect); - if (!pBack) { - return TRUE; - } - pBack->CompositeBitmap(0, 0, pBack->GetWidth(), pBack->GetHeight(), m_pBitmap, 0, 0); - } else { - pBack = m_pBitmap->Clone(&rect); - } - if (!pBack) { - return TRUE; - } - FX_BOOL bRet = TRUE; - left = left >= 0 ? 0 : left; - top = top >= 0 ? 0 : top; +FX_BOOL CFX_AggDeviceDriver::GetDIBits(CFX_DIBitmap* pBitmap, + int left, + int top, + void* pIccTransform, + FX_BOOL bDEdge) { + if (m_pBitmap->GetBuffer() == NULL) { + return TRUE; + } + if (bDEdge) { if (m_bRgbByteOrder) { - RgbByteOrderTransferBitmap(pBitmap, 0, 0, rect.Width(), rect.Height(), pBack, left, top); + RgbByteOrderTransferBitmap(pBitmap, 0, 0, pBitmap->GetWidth(), + pBitmap->GetHeight(), m_pBitmap, left, top); } else { - bRet = pBitmap->TransferBitmap(0, 0, rect.Width(), rect.Height(), pBack, left, top, pIccTransform); + return pBitmap->TransferBitmap(0, 0, pBitmap->GetWidth(), + pBitmap->GetHeight(), m_pBitmap, left, top, + pIccTransform); } - delete pBack; - return bRet; + return TRUE; + } + FX_RECT rect(left, top, left + pBitmap->GetWidth(), + top + pBitmap->GetHeight()); + CFX_DIBitmap* pBack = NULL; + if (m_pOriDevice) { + pBack = m_pOriDevice->Clone(&rect); + if (!pBack) { + return TRUE; + } + pBack->CompositeBitmap(0, 0, pBack->GetWidth(), pBack->GetHeight(), + m_pBitmap, 0, 0); + } else { + pBack = m_pBitmap->Clone(&rect); + } + if (!pBack) { + return TRUE; + } + FX_BOOL bRet = TRUE; + left = left >= 0 ? 0 : left; + top = top >= 0 ? 0 : top; + if (m_bRgbByteOrder) { + RgbByteOrderTransferBitmap(pBitmap, 0, 0, rect.Width(), rect.Height(), + pBack, left, top); + } else { + bRet = pBitmap->TransferBitmap(0, 0, rect.Width(), rect.Height(), pBack, + left, top, pIccTransform); + } + delete pBack; + return bRet; } -FX_BOOL CFX_AggDeviceDriver::SetDIBits(const CFX_DIBSource* pBitmap, FX_DWORD argb, const FX_RECT* pSrcRect, int left, int top, int blend_type, - int alpha_flag, void* pIccTransform) -{ - if (m_pBitmap->GetBuffer() == NULL) { - return TRUE; - } - if (pBitmap->IsAlphaMask()) - return m_pBitmap->CompositeMask(left, top, pSrcRect->Width(), pSrcRect->Height(), pBitmap, argb, - pSrcRect->left, pSrcRect->top, blend_type, m_pClipRgn, m_bRgbByteOrder, alpha_flag, pIccTransform); - return m_pBitmap->CompositeBitmap(left, top, pSrcRect->Width(), pSrcRect->Height(), pBitmap, - pSrcRect->left, pSrcRect->top, blend_type, m_pClipRgn, m_bRgbByteOrder, pIccTransform); +FX_BOOL CFX_AggDeviceDriver::SetDIBits(const CFX_DIBSource* pBitmap, + FX_DWORD argb, + const FX_RECT* pSrcRect, + int left, + int top, + int blend_type, + int alpha_flag, + void* pIccTransform) { + if (m_pBitmap->GetBuffer() == NULL) { + return TRUE; + } + if (pBitmap->IsAlphaMask()) + return m_pBitmap->CompositeMask( + left, top, pSrcRect->Width(), pSrcRect->Height(), pBitmap, argb, + pSrcRect->left, pSrcRect->top, blend_type, m_pClipRgn, m_bRgbByteOrder, + alpha_flag, pIccTransform); + return m_pBitmap->CompositeBitmap( + left, top, pSrcRect->Width(), pSrcRect->Height(), pBitmap, pSrcRect->left, + pSrcRect->top, blend_type, m_pClipRgn, m_bRgbByteOrder, pIccTransform); } -FX_BOOL CFX_AggDeviceDriver::StretchDIBits(const CFX_DIBSource* pSource, FX_DWORD argb, int dest_left, int dest_top, - int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags, - int alpha_flag, void* pIccTransform, int blend_type) -{ - if (m_pBitmap->GetBuffer() == NULL) { - return TRUE; - } - if (dest_width == pSource->GetWidth() && dest_height == pSource->GetHeight()) { - FX_RECT rect(0, 0, dest_width, dest_height); - return SetDIBits(pSource, argb, &rect, dest_left, dest_top, blend_type, alpha_flag, pIccTransform); - } - FX_RECT dest_rect(dest_left, dest_top, dest_left + dest_width, dest_top + dest_height); - dest_rect.Normalize(); - FX_RECT dest_clip = dest_rect; - dest_clip.Intersect(*pClipRect); - CFX_BitmapComposer composer; - composer.Compose(m_pBitmap, m_pClipRgn, 255, argb, dest_clip, FALSE, FALSE, FALSE, m_bRgbByteOrder, alpha_flag, pIccTransform, blend_type); - dest_clip.Offset(-dest_rect.left, -dest_rect.top); - CFX_ImageStretcher stretcher; - if (stretcher.Start(&composer, pSource, dest_width, dest_height, dest_clip, flags)) { - stretcher.Continue(NULL); - } +FX_BOOL CFX_AggDeviceDriver::StretchDIBits(const CFX_DIBSource* pSource, + FX_DWORD argb, + int dest_left, + int dest_top, + int dest_width, + int dest_height, + const FX_RECT* pClipRect, + FX_DWORD flags, + int alpha_flag, + void* pIccTransform, + int blend_type) { + if (m_pBitmap->GetBuffer() == NULL) { return TRUE; + } + if (dest_width == pSource->GetWidth() && + dest_height == pSource->GetHeight()) { + FX_RECT rect(0, 0, dest_width, dest_height); + return SetDIBits(pSource, argb, &rect, dest_left, dest_top, blend_type, + alpha_flag, pIccTransform); + } + FX_RECT dest_rect(dest_left, dest_top, dest_left + dest_width, + dest_top + dest_height); + dest_rect.Normalize(); + FX_RECT dest_clip = dest_rect; + dest_clip.Intersect(*pClipRect); + CFX_BitmapComposer composer; + composer.Compose(m_pBitmap, m_pClipRgn, 255, argb, dest_clip, FALSE, FALSE, + FALSE, m_bRgbByteOrder, alpha_flag, pIccTransform, + blend_type); + dest_clip.Offset(-dest_rect.left, -dest_rect.top); + CFX_ImageStretcher stretcher; + if (stretcher.Start(&composer, pSource, dest_width, dest_height, dest_clip, + flags)) { + stretcher.Continue(NULL); + } + return TRUE; } -FX_BOOL CFX_AggDeviceDriver::StartDIBits(const CFX_DIBSource* pSource, int bitmap_alpha, FX_DWORD argb, - const CFX_AffineMatrix* pMatrix, FX_DWORD render_flags, void*& handle, - int alpha_flag, void* pIccTransform, int blend_type) -{ - if (m_pBitmap->GetBuffer() == NULL) { - return TRUE; - } - CFX_ImageRenderer* pRenderer = new CFX_ImageRenderer; - pRenderer->Start(m_pBitmap, m_pClipRgn, pSource, bitmap_alpha, argb, pMatrix, render_flags, m_bRgbByteOrder, alpha_flag, pIccTransform); - handle = pRenderer; +FX_BOOL CFX_AggDeviceDriver::StartDIBits(const CFX_DIBSource* pSource, + int bitmap_alpha, + FX_DWORD argb, + const CFX_AffineMatrix* pMatrix, + FX_DWORD render_flags, + void*& handle, + int alpha_flag, + void* pIccTransform, + int blend_type) { + if (m_pBitmap->GetBuffer() == NULL) { return TRUE; + } + CFX_ImageRenderer* pRenderer = new CFX_ImageRenderer; + pRenderer->Start(m_pBitmap, m_pClipRgn, pSource, bitmap_alpha, argb, pMatrix, + render_flags, m_bRgbByteOrder, alpha_flag, pIccTransform); + handle = pRenderer; + return TRUE; } -FX_BOOL CFX_AggDeviceDriver::ContinueDIBits(void* pHandle, IFX_Pause* pPause) -{ - if (m_pBitmap->GetBuffer() == NULL) { - return TRUE; - } - return ((CFX_ImageRenderer*)pHandle)->Continue(pPause); +FX_BOOL CFX_AggDeviceDriver::ContinueDIBits(void* pHandle, IFX_Pause* pPause) { + if (m_pBitmap->GetBuffer() == NULL) { + return TRUE; + } + return ((CFX_ImageRenderer*)pHandle)->Continue(pPause); } -void CFX_AggDeviceDriver::CancelDIBits(void* pHandle) -{ - if (m_pBitmap->GetBuffer() == NULL) { - return; - } - delete (CFX_ImageRenderer*)pHandle; +void CFX_AggDeviceDriver::CancelDIBits(void* pHandle) { + if (m_pBitmap->GetBuffer() == NULL) { + return; + } + delete (CFX_ImageRenderer*)pHandle; } -CFX_FxgeDevice::CFX_FxgeDevice() -{ - m_bOwnedBitmap = FALSE; +CFX_FxgeDevice::CFX_FxgeDevice() { + m_bOwnedBitmap = FALSE; } -FX_BOOL CFX_FxgeDevice::Attach(CFX_DIBitmap* pBitmap, int dither_bits, FX_BOOL bRgbByteOrder, CFX_DIBitmap* pOriDevice, FX_BOOL bGroupKnockout) -{ - if (pBitmap == NULL) { - return FALSE; - } - SetBitmap(pBitmap); - IFX_RenderDeviceDriver* pDriver = new CFX_AggDeviceDriver(pBitmap, dither_bits, bRgbByteOrder, pOriDevice, bGroupKnockout); - SetDeviceDriver(pDriver); - return TRUE; +FX_BOOL CFX_FxgeDevice::Attach(CFX_DIBitmap* pBitmap, + int dither_bits, + FX_BOOL bRgbByteOrder, + CFX_DIBitmap* pOriDevice, + FX_BOOL bGroupKnockout) { + if (pBitmap == NULL) { + return FALSE; + } + SetBitmap(pBitmap); + IFX_RenderDeviceDriver* pDriver = new CFX_AggDeviceDriver( + pBitmap, dither_bits, bRgbByteOrder, pOriDevice, bGroupKnockout); + SetDeviceDriver(pDriver); + return TRUE; } -FX_BOOL CFX_FxgeDevice::Create(int width, int height, FXDIB_Format format, int dither_bits, CFX_DIBitmap* pOriDevice) -{ - m_bOwnedBitmap = TRUE; - CFX_DIBitmap* pBitmap = new CFX_DIBitmap; - if (!pBitmap->Create(width, height, format)) { - delete pBitmap; - return FALSE; - } - SetBitmap(pBitmap); - IFX_RenderDeviceDriver* pDriver = new CFX_AggDeviceDriver(pBitmap, dither_bits, FALSE, pOriDevice, FALSE); - SetDeviceDriver(pDriver); - return TRUE; +FX_BOOL CFX_FxgeDevice::Create(int width, + int height, + FXDIB_Format format, + int dither_bits, + CFX_DIBitmap* pOriDevice) { + m_bOwnedBitmap = TRUE; + CFX_DIBitmap* pBitmap = new CFX_DIBitmap; + if (!pBitmap->Create(width, height, format)) { + delete pBitmap; + return FALSE; + } + SetBitmap(pBitmap); + IFX_RenderDeviceDriver* pDriver = + new CFX_AggDeviceDriver(pBitmap, dither_bits, FALSE, pOriDevice, FALSE); + SetDeviceDriver(pDriver); + return TRUE; } -CFX_FxgeDevice::~CFX_FxgeDevice() -{ - if (m_bOwnedBitmap) { - delete GetBitmap(); - } +CFX_FxgeDevice::~CFX_FxgeDevice() { + if (m_bOwnedBitmap) { + delete GetBitmap(); + } } diff --git a/core/src/fxge/android/fpf_skiafont.cpp b/core/src/fxge/android/fpf_skiafont.cpp index 2dad01057a..ba202acc92 100644 --- a/core/src/fxge/android/fpf_skiafont.cpp +++ b/core/src/fxge/android/fpf_skiafont.cpp @@ -8,197 +8,203 @@ #if _FX_OS_ == _FX_ANDROID_ #include "fpf_skiafont.h" #include "fpf_skiafontmgr.h" -#define FPF_EM_ADJUST(em, a) (em == 0 ? (a) : (a) * 1000 / em) +#define FPF_EM_ADJUST(em, a) (em == 0 ? (a) : (a)*1000 / em) CFPF_SkiaFont::CFPF_SkiaFont() - : m_pFontMgr(NULL) - , m_pFontDes(NULL) - , m_Face(NULL) - , m_dwStyle(0) - , m_uCharset(0) - , m_dwRefCount(0) -{ -} -CFPF_SkiaFont::~CFPF_SkiaFont() -{ - if (m_Face) { - FXFT_Done_Face(m_Face); - } -} -void CFPF_SkiaFont::Release() -{ - if (--m_dwRefCount == 0) { - delete this; - } -} -IFPF_Font* CFPF_SkiaFont::Retain() -{ - m_dwRefCount++; - return (IFPF_Font*)this; -} -FPF_HFONT CFPF_SkiaFont::GetHandle() -{ - return NULL; -} -CFX_ByteString CFPF_SkiaFont::GetFamilyName() -{ - if (!m_Face) { - return CFX_ByteString(); - } - return CFX_ByteString(FXFT_Get_Face_Family_Name(m_Face)); -} -CFX_WideString CFPF_SkiaFont::GetPsName() -{ - if (!m_Face) { - return CFX_WideString(); - } - return CFX_WideString::FromLocal(FXFT_Get_Postscript_Name(m_Face)); -} -int32_t CFPF_SkiaFont::GetGlyphIndex(FX_WCHAR wUnicode) -{ - if (!m_Face) { - return wUnicode; - } - if (FXFT_Select_Charmap(m_Face, FXFT_ENCODING_UNICODE)) { - return 0; - } - return FXFT_Get_Char_Index(m_Face, wUnicode); -} -int32_t CFPF_SkiaFont::GetGlyphWidth(int32_t iGlyphIndex) -{ - if (!m_Face) { - return 0; - } - if (FXFT_Load_Glyph(m_Face, iGlyphIndex, FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) { - return 0; - } - return FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Glyph_HoriAdvance(m_Face)); -} -int32_t CFPF_SkiaFont::GetAscent() const -{ - if (!m_Face) { - return 0; - } - return FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_Ascender(m_Face)); -} -int32_t CFPF_SkiaFont::GetDescent() const -{ - if (!m_Face) { - return 0; - } - return FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_Descender(m_Face)); + : m_pFontMgr(NULL), + m_pFontDes(NULL), + m_Face(NULL), + m_dwStyle(0), + m_uCharset(0), + m_dwRefCount(0) {} +CFPF_SkiaFont::~CFPF_SkiaFont() { + if (m_Face) { + FXFT_Done_Face(m_Face); + } +} +void CFPF_SkiaFont::Release() { + if (--m_dwRefCount == 0) { + delete this; + } +} +IFPF_Font* CFPF_SkiaFont::Retain() { + m_dwRefCount++; + return (IFPF_Font*)this; +} +FPF_HFONT CFPF_SkiaFont::GetHandle() { + return NULL; +} +CFX_ByteString CFPF_SkiaFont::GetFamilyName() { + if (!m_Face) { + return CFX_ByteString(); + } + return CFX_ByteString(FXFT_Get_Face_Family_Name(m_Face)); +} +CFX_WideString CFPF_SkiaFont::GetPsName() { + if (!m_Face) { + return CFX_WideString(); + } + return CFX_WideString::FromLocal(FXFT_Get_Postscript_Name(m_Face)); +} +int32_t CFPF_SkiaFont::GetGlyphIndex(FX_WCHAR wUnicode) { + if (!m_Face) { + return wUnicode; + } + if (FXFT_Select_Charmap(m_Face, FXFT_ENCODING_UNICODE)) { + return 0; + } + return FXFT_Get_Char_Index(m_Face, wUnicode); } -FX_BOOL CFPF_SkiaFont::GetGlyphBBox(int32_t iGlyphIndex, FX_RECT &rtBBox) -{ - if (!m_Face) { - return FALSE; - } - if (FXFT_Is_Face_Tricky(m_Face)) { - if (FXFT_Set_Char_Size(m_Face, 0, 1000 * 64, 72, 72)) { - return FALSE; - } - if (FXFT_Load_Glyph(m_Face, iGlyphIndex, FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) { - FXFT_Set_Pixel_Sizes(m_Face, 0, 64); - return FALSE; - } - FXFT_Glyph glyph; - if (FXFT_Get_Glyph(m_Face->glyph, &glyph)) { - FXFT_Set_Pixel_Sizes(m_Face, 0, 64); - return FALSE; - } - FXFT_BBox cbox; - FXFT_Glyph_Get_CBox(glyph, FXFT_GLYPH_BBOX_PIXELS, &cbox); - int32_t x_ppem = m_Face->size->metrics.x_ppem; - int32_t y_ppem = m_Face->size->metrics.y_ppem; - rtBBox.left = FPF_EM_ADJUST(x_ppem, cbox.xMin); - rtBBox.right = FPF_EM_ADJUST(x_ppem, cbox.xMax); - rtBBox.top = FPF_EM_ADJUST(y_ppem, cbox.yMax); - rtBBox.bottom = FPF_EM_ADJUST(y_ppem, cbox.yMin); - rtBBox.top = FX_MIN(rtBBox.top, GetAscent()); - rtBBox.bottom = FX_MAX(rtBBox.bottom, GetDescent()); - FXFT_Done_Glyph(glyph); - return FXFT_Set_Pixel_Sizes(m_Face, 0, 64) == 0; - } - if (FXFT_Load_Glyph(m_Face, iGlyphIndex, FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) { - return FALSE; - } - rtBBox.left = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Glyph_HoriBearingX(m_Face)); - rtBBox.bottom = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Glyph_HoriBearingY(m_Face)); - rtBBox.right = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Glyph_HoriBearingX(m_Face) + FXFT_Get_Glyph_Width(m_Face)); - rtBBox.top = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Glyph_HoriBearingY(m_Face) - FXFT_Get_Glyph_Height(m_Face)); - return TRUE; -} -FX_BOOL CFPF_SkiaFont::GetBBox(FX_RECT &rtBBox) -{ - if (!m_Face) { - return FALSE; - } - rtBBox.left = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_xMin(m_Face)); - rtBBox.top = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_yMin(m_Face)); - rtBBox.right = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_xMax(m_Face)); - rtBBox.bottom = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_yMax(m_Face)); - return TRUE; -} -int32_t CFPF_SkiaFont::GetHeight() const -{ - if (!m_Face) { - return 0; - } - return FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_Height(m_Face)); +int32_t CFPF_SkiaFont::GetGlyphWidth(int32_t iGlyphIndex) { + if (!m_Face) { + return 0; + } + if (FXFT_Load_Glyph( + m_Face, iGlyphIndex, + FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) { + return 0; + } + return FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), + FXFT_Get_Glyph_HoriAdvance(m_Face)); } -int32_t CFPF_SkiaFont::GetItalicAngle() const -{ - if (!m_Face) { - return 0; - } - TT_Postscript *ttInfo = (TT_Postscript*)FT_Get_Sfnt_Table(m_Face, ft_sfnt_post); - if (ttInfo) { - return ttInfo->italicAngle; - } +int32_t CFPF_SkiaFont::GetAscent() const { + if (!m_Face) { return 0; + } + return FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), + FXFT_Get_Face_Ascender(m_Face)); } -FX_DWORD CFPF_SkiaFont::GetFontData(FX_DWORD dwTable, uint8_t* pBuffer, FX_DWORD dwSize) -{ - if (!m_Face) { - return 0; - } - FT_ULong ulSize = pdfium::base::checked_cast(dwSize); - if (FXFT_Load_Sfnt_Table(m_Face, dwTable, 0, pBuffer, &ulSize)) { - return 0; - } - return pdfium::base::checked_cast(ulSize); +int32_t CFPF_SkiaFont::GetDescent() const { + if (!m_Face) { + return 0; + } + return FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), + FXFT_Get_Face_Descender(m_Face)); +} +FX_BOOL CFPF_SkiaFont::GetGlyphBBox(int32_t iGlyphIndex, FX_RECT& rtBBox) { + if (!m_Face) { + return FALSE; + } + if (FXFT_Is_Face_Tricky(m_Face)) { + if (FXFT_Set_Char_Size(m_Face, 0, 1000 * 64, 72, 72)) { + return FALSE; + } + if (FXFT_Load_Glyph(m_Face, iGlyphIndex, + FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) { + FXFT_Set_Pixel_Sizes(m_Face, 0, 64); + return FALSE; + } + FXFT_Glyph glyph; + if (FXFT_Get_Glyph(m_Face->glyph, &glyph)) { + FXFT_Set_Pixel_Sizes(m_Face, 0, 64); + return FALSE; + } + FXFT_BBox cbox; + FXFT_Glyph_Get_CBox(glyph, FXFT_GLYPH_BBOX_PIXELS, &cbox); + int32_t x_ppem = m_Face->size->metrics.x_ppem; + int32_t y_ppem = m_Face->size->metrics.y_ppem; + rtBBox.left = FPF_EM_ADJUST(x_ppem, cbox.xMin); + rtBBox.right = FPF_EM_ADJUST(x_ppem, cbox.xMax); + rtBBox.top = FPF_EM_ADJUST(y_ppem, cbox.yMax); + rtBBox.bottom = FPF_EM_ADJUST(y_ppem, cbox.yMin); + rtBBox.top = FX_MIN(rtBBox.top, GetAscent()); + rtBBox.bottom = FX_MAX(rtBBox.bottom, GetDescent()); + FXFT_Done_Glyph(glyph); + return FXFT_Set_Pixel_Sizes(m_Face, 0, 64) == 0; + } + if (FXFT_Load_Glyph( + m_Face, iGlyphIndex, + FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) { + return FALSE; + } + rtBBox.left = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), + FXFT_Get_Glyph_HoriBearingX(m_Face)); + rtBBox.bottom = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), + FXFT_Get_Glyph_HoriBearingY(m_Face)); + rtBBox.right = FPF_EM_ADJUST( + FXFT_Get_Face_UnitsPerEM(m_Face), + FXFT_Get_Glyph_HoriBearingX(m_Face) + FXFT_Get_Glyph_Width(m_Face)); + rtBBox.top = FPF_EM_ADJUST( + FXFT_Get_Face_UnitsPerEM(m_Face), + FXFT_Get_Glyph_HoriBearingY(m_Face) - FXFT_Get_Glyph_Height(m_Face)); + return TRUE; +} +FX_BOOL CFPF_SkiaFont::GetBBox(FX_RECT& rtBBox) { + if (!m_Face) { + return FALSE; + } + rtBBox.left = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), + FXFT_Get_Face_xMin(m_Face)); + rtBBox.top = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), + FXFT_Get_Face_yMin(m_Face)); + rtBBox.right = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), + FXFT_Get_Face_xMax(m_Face)); + rtBBox.bottom = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), + FXFT_Get_Face_yMax(m_Face)); + return TRUE; +} +int32_t CFPF_SkiaFont::GetHeight() const { + if (!m_Face) { + return 0; + } + return FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), + FXFT_Get_Face_Height(m_Face)); } -FX_BOOL CFPF_SkiaFont::InitFont(CFPF_SkiaFontMgr *pFontMgr, CFPF_SkiaFontDescriptor *pFontDes, const CFX_ByteStringC& bsFamily, FX_DWORD dwStyle, uint8_t uCharset) -{ - if (!pFontMgr || !pFontDes) { - return FALSE; - } - switch (pFontDes->GetType()) { - case FPF_SKIAFONTTYPE_Path: { - CFPF_SkiaPathFont *pFont = (CFPF_SkiaPathFont*)pFontDes; - m_Face = pFontMgr->GetFontFace(pFont->m_pPath, pFont->m_iFaceIndex); - } - break; - case FPF_SKIAFONTTYPE_File: { - CFPF_SkiaFileFont *pFont = (CFPF_SkiaFileFont*)pFontDes; - m_Face = pFontMgr->GetFontFace(pFont->m_pFile, pFont->m_iFaceIndex); - } - break; - case FPF_SKIAFONTTYPE_Buffer: { - CFPF_SkiaBufferFont *pFont = (CFPF_SkiaBufferFont*)pFontDes; - m_Face = pFontMgr->GetFontFace((const uint8_t*)pFont->m_pBuffer, pFont->m_szBuffer, pFont->m_iFaceIndex); - } - break; - default: - return FALSE; - } - if (!m_Face) { - return FALSE; - } - m_dwStyle = dwStyle; - m_uCharset = uCharset; - m_pFontMgr = pFontMgr; - m_pFontDes = pFontDes; - m_dwRefCount = 1; - return TRUE; +int32_t CFPF_SkiaFont::GetItalicAngle() const { + if (!m_Face) { + return 0; + } + TT_Postscript* ttInfo = + (TT_Postscript*)FT_Get_Sfnt_Table(m_Face, ft_sfnt_post); + if (ttInfo) { + return ttInfo->italicAngle; + } + return 0; +} +FX_DWORD CFPF_SkiaFont::GetFontData(FX_DWORD dwTable, + uint8_t* pBuffer, + FX_DWORD dwSize) { + if (!m_Face) { + return 0; + } + FT_ULong ulSize = pdfium::base::checked_cast(dwSize); + if (FXFT_Load_Sfnt_Table(m_Face, dwTable, 0, pBuffer, &ulSize)) { + return 0; + } + return pdfium::base::checked_cast(ulSize); +} +FX_BOOL CFPF_SkiaFont::InitFont(CFPF_SkiaFontMgr* pFontMgr, + CFPF_SkiaFontDescriptor* pFontDes, + const CFX_ByteStringC& bsFamily, + FX_DWORD dwStyle, + uint8_t uCharset) { + if (!pFontMgr || !pFontDes) { + return FALSE; + } + switch (pFontDes->GetType()) { + case FPF_SKIAFONTTYPE_Path: { + CFPF_SkiaPathFont* pFont = (CFPF_SkiaPathFont*)pFontDes; + m_Face = pFontMgr->GetFontFace(pFont->m_pPath, pFont->m_iFaceIndex); + } break; + case FPF_SKIAFONTTYPE_File: { + CFPF_SkiaFileFont* pFont = (CFPF_SkiaFileFont*)pFontDes; + m_Face = pFontMgr->GetFontFace(pFont->m_pFile, pFont->m_iFaceIndex); + } break; + case FPF_SKIAFONTTYPE_Buffer: { + CFPF_SkiaBufferFont* pFont = (CFPF_SkiaBufferFont*)pFontDes; + m_Face = pFontMgr->GetFontFace((const uint8_t*)pFont->m_pBuffer, + pFont->m_szBuffer, pFont->m_iFaceIndex); + } break; + default: + return FALSE; + } + if (!m_Face) { + return FALSE; + } + m_dwStyle = dwStyle; + m_uCharset = uCharset; + m_pFontMgr = pFontMgr; + m_pFontDes = pFontDes; + m_dwRefCount = 1; + return TRUE; } #endif diff --git a/core/src/fxge/android/fpf_skiafont.h b/core/src/fxge/android/fpf_skiafont.h index 49819d4c11..4a841940df 100644 --- a/core/src/fxge/android/fpf_skiafont.h +++ b/core/src/fxge/android/fpf_skiafont.h @@ -11,48 +11,48 @@ class CFPF_SkiaFontDescriptor; class CFPF_SkiaFontMgr; class SkTypeface; -class CFPF_SkiaFont : public IFPF_Font -{ -public: - CFPF_SkiaFont(); - virtual ~CFPF_SkiaFont(); - virtual void Release(); - virtual IFPF_Font* Retain(); - - virtual FPF_HFONT GetHandle(); - - virtual CFX_ByteString GetFamilyName(); - virtual CFX_WideString GetPsName(); - - virtual FX_DWORD GetFontStyle() const - { - return m_dwStyle; - } - virtual uint8_t GetCharset() const - { - return m_uCharset; - } - - virtual int32_t GetGlyphIndex(FX_WCHAR wUnicode); - virtual int32_t GetGlyphWidth(int32_t iGlyphIndex); - - virtual int32_t GetAscent() const; - virtual int32_t GetDescent() const; - - virtual FX_BOOL GetGlyphBBox(int32_t iGlyphIndex, FX_RECT &rtBBox); - virtual FX_BOOL GetBBox(FX_RECT &rtBBox); - - virtual int32_t GetHeight() const; - virtual int32_t GetItalicAngle() const; - virtual FX_DWORD GetFontData(FX_DWORD dwTable, uint8_t* pBuffer, FX_DWORD dwSize); - FX_BOOL InitFont(CFPF_SkiaFontMgr *pFontMgr, CFPF_SkiaFontDescriptor *pFontDes, const CFX_ByteStringC& bsFamily, FX_DWORD dwStyle, uint8_t uCharset); -protected: - CFPF_SkiaFontMgr *m_pFontMgr; - CFPF_SkiaFontDescriptor *m_pFontDes; - FXFT_Face m_Face; - FX_DWORD m_dwStyle; - uint8_t m_uCharset; - FX_DWORD m_dwRefCount; +class CFPF_SkiaFont : public IFPF_Font { + public: + CFPF_SkiaFont(); + virtual ~CFPF_SkiaFont(); + virtual void Release(); + virtual IFPF_Font* Retain(); + + virtual FPF_HFONT GetHandle(); + + virtual CFX_ByteString GetFamilyName(); + virtual CFX_WideString GetPsName(); + + virtual FX_DWORD GetFontStyle() const { return m_dwStyle; } + virtual uint8_t GetCharset() const { return m_uCharset; } + + virtual int32_t GetGlyphIndex(FX_WCHAR wUnicode); + virtual int32_t GetGlyphWidth(int32_t iGlyphIndex); + + virtual int32_t GetAscent() const; + virtual int32_t GetDescent() const; + + virtual FX_BOOL GetGlyphBBox(int32_t iGlyphIndex, FX_RECT& rtBBox); + virtual FX_BOOL GetBBox(FX_RECT& rtBBox); + + virtual int32_t GetHeight() const; + virtual int32_t GetItalicAngle() const; + virtual FX_DWORD GetFontData(FX_DWORD dwTable, + uint8_t* pBuffer, + FX_DWORD dwSize); + FX_BOOL InitFont(CFPF_SkiaFontMgr* pFontMgr, + CFPF_SkiaFontDescriptor* pFontDes, + const CFX_ByteStringC& bsFamily, + FX_DWORD dwStyle, + uint8_t uCharset); + + protected: + CFPF_SkiaFontMgr* m_pFontMgr; + CFPF_SkiaFontDescriptor* m_pFontDes; + FXFT_Face m_Face; + FX_DWORD m_dwStyle; + uint8_t m_uCharset; + FX_DWORD m_dwRefCount; }; #endif diff --git a/core/src/fxge/android/fpf_skiafontmgr.cpp b/core/src/fxge/android/fpf_skiafontmgr.cpp index 86bb052435..b18e9c83be 100644 --- a/core/src/fxge/android/fpf_skiafontmgr.cpp +++ b/core/src/fxge/android/fpf_skiafontmgr.cpp @@ -6,466 +6,446 @@ #include "fx_fpf.h" #if _FX_OS_ == _FX_ANDROID_ -#define FPF_SKIAMATCHWEIGHT_NAME1 62 -#define FPF_SKIAMATCHWEIGHT_NAME2 60 -#define FPF_SKIAMATCHWEIGHT_1 16 -#define FPF_SKIAMATCHWEIGHT_2 8 +#define FPF_SKIAMATCHWEIGHT_NAME1 62 +#define FPF_SKIAMATCHWEIGHT_NAME2 60 +#define FPF_SKIAMATCHWEIGHT_1 16 +#define FPF_SKIAMATCHWEIGHT_2 8 #include "fpf_skiafontmgr.h" #include "fpf_skiafont.h" #ifdef __cplusplus extern "C" { #endif -static unsigned long FPF_SkiaStream_Read(FXFT_Stream stream, unsigned long offset, unsigned char* buffer, unsigned long count) -{ - IFX_FileRead *pFileRead = (IFX_FileRead*)stream->descriptor.pointer; - if (!pFileRead) { - return 0; - } - if (count > 0) { - if (pFileRead->ReadBlock(buffer, (FX_FILESIZE)offset, (size_t)count) != count) { - return 0; - } - } - return count; -} -static void FPF_SkiaStream_Close(FXFT_Stream stream) -{ +static unsigned long FPF_SkiaStream_Read(FXFT_Stream stream, + unsigned long offset, + unsigned char* buffer, + unsigned long count) { + IFX_FileRead* pFileRead = (IFX_FileRead*)stream->descriptor.pointer; + if (!pFileRead) { + return 0; + } + if (count > 0) { + if (pFileRead->ReadBlock(buffer, (FX_FILESIZE)offset, (size_t)count) != + count) { + return 0; + } + } + return count; } +static void FPF_SkiaStream_Close(FXFT_Stream stream) {} #ifdef __cplusplus }; #endif typedef struct _FPF_SKIAFONTMAP { - FX_DWORD dwFamily; - FX_DWORD dwSubSt; + FX_DWORD dwFamily; + FX_DWORD dwSubSt; } FPF_SKIAFONTMAP, *FPF_LPSKIAFONTMAP; -typedef FPF_SKIAFONTMAP const * FPF_LPCSKIAFONTMAP; +typedef FPF_SKIAFONTMAP const* FPF_LPCSKIAFONTMAP; static const FPF_SKIAFONTMAP g_SkiaFontmap[] = { - {0x58c5083, 0xc8d2e345}, - {0x5dfade2, 0xe1633081}, - {0x684317d, 0xe1633081}, - {0x14ee2d13, 0xc8d2e345}, - {0x3918fe2d, 0xbbeeec72}, - {0x3b98b31c, 0xe1633081}, - {0x3d49f40e, 0xe1633081}, - {0x432c41c5, 0xe1633081}, - {0x491b6ad0, 0xe1633081}, - {0x5612cab1, 0x59b9f8f1}, - {0x779ce19d, 0xc8d2e345}, - {0x7cc9510b, 0x59b9f8f1}, - {0x83746053, 0xbbeeec72}, - {0xaaa60c03, 0xbbeeec72}, - {0xbf85ff26, 0xe1633081}, - {0xc04fe601, 0xbbeeec72}, - {0xca3812d5, 0x59b9f8f1}, - {0xca383e15, 0x59b9f8f1}, - {0xcad5eaf6, 0x59b9f8f1}, - {0xcb7a04c8, 0xc8d2e345}, - {0xfb4ce0de, 0xe1633081}, + {0x58c5083, 0xc8d2e345}, {0x5dfade2, 0xe1633081}, + {0x684317d, 0xe1633081}, {0x14ee2d13, 0xc8d2e345}, + {0x3918fe2d, 0xbbeeec72}, {0x3b98b31c, 0xe1633081}, + {0x3d49f40e, 0xe1633081}, {0x432c41c5, 0xe1633081}, + {0x491b6ad0, 0xe1633081}, {0x5612cab1, 0x59b9f8f1}, + {0x779ce19d, 0xc8d2e345}, {0x7cc9510b, 0x59b9f8f1}, + {0x83746053, 0xbbeeec72}, {0xaaa60c03, 0xbbeeec72}, + {0xbf85ff26, 0xe1633081}, {0xc04fe601, 0xbbeeec72}, + {0xca3812d5, 0x59b9f8f1}, {0xca383e15, 0x59b9f8f1}, + {0xcad5eaf6, 0x59b9f8f1}, {0xcb7a04c8, 0xc8d2e345}, + {0xfb4ce0de, 0xe1633081}, }; -FX_DWORD FPF_SkiaGetSubstFont(FX_DWORD dwHash) -{ - int32_t iStart = 0; - int32_t iEnd = sizeof(g_SkiaFontmap) / sizeof(FPF_SKIAFONTMAP); - while (iStart <= iEnd) { - int32_t iMid = (iStart + iEnd) / 2; - FPF_LPCSKIAFONTMAP pItem = &g_SkiaFontmap[iMid]; - if (dwHash < pItem->dwFamily) { - iEnd = iMid - 1; - } else if (dwHash > pItem->dwFamily) { - iStart = iMid + 1; - } else { - return pItem->dwSubSt; - } +FX_DWORD FPF_SkiaGetSubstFont(FX_DWORD dwHash) { + int32_t iStart = 0; + int32_t iEnd = sizeof(g_SkiaFontmap) / sizeof(FPF_SKIAFONTMAP); + while (iStart <= iEnd) { + int32_t iMid = (iStart + iEnd) / 2; + FPF_LPCSKIAFONTMAP pItem = &g_SkiaFontmap[iMid]; + if (dwHash < pItem->dwFamily) { + iEnd = iMid - 1; + } else if (dwHash > pItem->dwFamily) { + iStart = iMid + 1; + } else { + return pItem->dwSubSt; } - return 0; + } + return 0; } static const FPF_SKIAFONTMAP g_SkiaSansFontMap[] = { - {0x58c5083, 0xd5b8d10f}, - {0x14ee2d13, 0xd5b8d10f}, - {0x779ce19d, 0xd5b8d10f}, - {0xcb7a04c8, 0xd5b8d10f}, - {0xfb4ce0de, 0xd5b8d10f}, + {0x58c5083, 0xd5b8d10f}, {0x14ee2d13, 0xd5b8d10f}, + {0x779ce19d, 0xd5b8d10f}, {0xcb7a04c8, 0xd5b8d10f}, + {0xfb4ce0de, 0xd5b8d10f}, }; -FX_DWORD FPF_SkiaGetSansFont(FX_DWORD dwHash) -{ - int32_t iStart = 0; - int32_t iEnd = sizeof(g_SkiaSansFontMap) / sizeof(FPF_SKIAFONTMAP); - while (iStart <= iEnd) { - int32_t iMid = (iStart + iEnd) / 2; - FPF_LPCSKIAFONTMAP pItem = &g_SkiaSansFontMap[iMid]; - if (dwHash < pItem->dwFamily) { - iEnd = iMid - 1; - } else if (dwHash > pItem->dwFamily) { - iStart = iMid + 1; - } else { - return pItem->dwSubSt; - } - } - return 0; -} -static uint32_t FPF_GetHashCode_StringA(const FX_CHAR* pStr, int32_t iLength, FX_BOOL bIgnoreCase = FALSE) -{ - if (!pStr) { - return 0; - } - if (iLength < 0) { - iLength = FXSYS_strlen(pStr); - } - const FX_CHAR* pStrEnd = pStr + iLength; - uint32_t uHashCode = 0; - if (bIgnoreCase) { - while (pStr < pStrEnd) { - uHashCode = 31 * uHashCode + FXSYS_tolower(*pStr++); - } +FX_DWORD FPF_SkiaGetSansFont(FX_DWORD dwHash) { + int32_t iStart = 0; + int32_t iEnd = sizeof(g_SkiaSansFontMap) / sizeof(FPF_SKIAFONTMAP); + while (iStart <= iEnd) { + int32_t iMid = (iStart + iEnd) / 2; + FPF_LPCSKIAFONTMAP pItem = &g_SkiaSansFontMap[iMid]; + if (dwHash < pItem->dwFamily) { + iEnd = iMid - 1; + } else if (dwHash > pItem->dwFamily) { + iStart = iMid + 1; } else { - while (pStr < pStrEnd) { - uHashCode = 31 * uHashCode + *pStr ++; - } + return pItem->dwSubSt; } - return uHashCode; + } + return 0; +} +static uint32_t FPF_GetHashCode_StringA(const FX_CHAR* pStr, + int32_t iLength, + FX_BOOL bIgnoreCase = FALSE) { + if (!pStr) { + return 0; + } + if (iLength < 0) { + iLength = FXSYS_strlen(pStr); + } + const FX_CHAR* pStrEnd = pStr + iLength; + uint32_t uHashCode = 0; + if (bIgnoreCase) { + while (pStr < pStrEnd) { + uHashCode = 31 * uHashCode + FXSYS_tolower(*pStr++); + } + } else { + while (pStr < pStrEnd) { + uHashCode = 31 * uHashCode + *pStr++; + } + } + return uHashCode; } enum FPF_SKIACHARSET { - FPF_SKIACHARSET_Ansi = 1 << 0, - FPF_SKIACHARSET_Default = 1 << 1, - FPF_SKIACHARSET_Symbol = 1 << 2, - FPF_SKIACHARSET_ShiftJIS = 1 << 3, - FPF_SKIACHARSET_Korean = 1 << 4, - FPF_SKIACHARSET_Johab = 1 << 5, - FPF_SKIACHARSET_GB2312 = 1 << 6, - FPF_SKIACHARSET_BIG5 = 1 << 7, - FPF_SKIACHARSET_Greek = 1 << 8, - FPF_SKIACHARSET_Turkish = 1 << 9, - FPF_SKIACHARSET_Vietnamese = 1 << 10, - FPF_SKIACHARSET_Hebrew = 1 << 11, - FPF_SKIACHARSET_Arabic = 1 << 12, - FPF_SKIACHARSET_Baltic = 1 << 13, - FPF_SKIACHARSET_Cyrillic = 1 << 14, - FPF_SKIACHARSET_Thai = 1 << 15, - FPF_SKIACHARSET_EeasternEuropean = 1 << 16, - FPF_SKIACHARSET_PC = 1 << 17, - FPF_SKIACHARSET_OEM = 1 << 18, + FPF_SKIACHARSET_Ansi = 1 << 0, + FPF_SKIACHARSET_Default = 1 << 1, + FPF_SKIACHARSET_Symbol = 1 << 2, + FPF_SKIACHARSET_ShiftJIS = 1 << 3, + FPF_SKIACHARSET_Korean = 1 << 4, + FPF_SKIACHARSET_Johab = 1 << 5, + FPF_SKIACHARSET_GB2312 = 1 << 6, + FPF_SKIACHARSET_BIG5 = 1 << 7, + FPF_SKIACHARSET_Greek = 1 << 8, + FPF_SKIACHARSET_Turkish = 1 << 9, + FPF_SKIACHARSET_Vietnamese = 1 << 10, + FPF_SKIACHARSET_Hebrew = 1 << 11, + FPF_SKIACHARSET_Arabic = 1 << 12, + FPF_SKIACHARSET_Baltic = 1 << 13, + FPF_SKIACHARSET_Cyrillic = 1 << 14, + FPF_SKIACHARSET_Thai = 1 << 15, + FPF_SKIACHARSET_EeasternEuropean = 1 << 16, + FPF_SKIACHARSET_PC = 1 << 17, + FPF_SKIACHARSET_OEM = 1 << 18, }; -static FX_DWORD FPF_SkiaGetCharset(uint8_t uCharset) -{ - switch (uCharset) { - case FXFONT_ANSI_CHARSET: - return FPF_SKIACHARSET_Ansi; - case FXFONT_DEFAULT_CHARSET: - return FPF_SKIACHARSET_Default; - case FXFONT_SYMBOL_CHARSET: - return FPF_SKIACHARSET_Symbol; - case FXFONT_SHIFTJIS_CHARSET: - return FPF_SKIACHARSET_ShiftJIS; - case FXFONT_HANGEUL_CHARSET: - return FPF_SKIACHARSET_Korean; - case FXFONT_GB2312_CHARSET: - return FPF_SKIACHARSET_GB2312; - case FXFONT_CHINESEBIG5_CHARSET: - return FPF_SKIACHARSET_BIG5; - case FXFONT_GREEK_CHARSET: - return FPF_SKIACHARSET_Greek; - case FXFONT_TURKISH_CHARSET: - return FPF_SKIACHARSET_Turkish; - case FXFONT_HEBREW_CHARSET: - return FPF_SKIACHARSET_Hebrew; - case FXFONT_ARABIC_CHARSET: - return FPF_SKIACHARSET_Arabic; - case FXFONT_BALTIC_CHARSET: - return FPF_SKIACHARSET_Baltic; - case FXFONT_RUSSIAN_CHARSET: - return FPF_SKIACHARSET_Cyrillic; - case FXFONT_THAI_CHARSET: - return FPF_SKIACHARSET_Thai; - case FXFONT_EASTEUROPE_CHARSET: - return FPF_SKIACHARSET_EeasternEuropean; - } - return FPF_SKIACHARSET_Default; -} -static FX_DWORD FPF_SKIANormalizeFontName(const CFX_ByteStringC& bsfamily) -{ - FX_DWORD dwHash = 0; - int32_t iLength = bsfamily.GetLength(); - const FX_CHAR* pBuffer = bsfamily.GetCStr(); - for (int32_t i = 0; i < iLength; i++) { - FX_CHAR ch = pBuffer[i]; - if (ch == ' ' || ch == '-' || ch == ',') { - continue; - } - dwHash = 31 * dwHash + FXSYS_tolower(ch); - } - return dwHash; +static FX_DWORD FPF_SkiaGetCharset(uint8_t uCharset) { + switch (uCharset) { + case FXFONT_ANSI_CHARSET: + return FPF_SKIACHARSET_Ansi; + case FXFONT_DEFAULT_CHARSET: + return FPF_SKIACHARSET_Default; + case FXFONT_SYMBOL_CHARSET: + return FPF_SKIACHARSET_Symbol; + case FXFONT_SHIFTJIS_CHARSET: + return FPF_SKIACHARSET_ShiftJIS; + case FXFONT_HANGEUL_CHARSET: + return FPF_SKIACHARSET_Korean; + case FXFONT_GB2312_CHARSET: + return FPF_SKIACHARSET_GB2312; + case FXFONT_CHINESEBIG5_CHARSET: + return FPF_SKIACHARSET_BIG5; + case FXFONT_GREEK_CHARSET: + return FPF_SKIACHARSET_Greek; + case FXFONT_TURKISH_CHARSET: + return FPF_SKIACHARSET_Turkish; + case FXFONT_HEBREW_CHARSET: + return FPF_SKIACHARSET_Hebrew; + case FXFONT_ARABIC_CHARSET: + return FPF_SKIACHARSET_Arabic; + case FXFONT_BALTIC_CHARSET: + return FPF_SKIACHARSET_Baltic; + case FXFONT_RUSSIAN_CHARSET: + return FPF_SKIACHARSET_Cyrillic; + case FXFONT_THAI_CHARSET: + return FPF_SKIACHARSET_Thai; + case FXFONT_EASTEUROPE_CHARSET: + return FPF_SKIACHARSET_EeasternEuropean; + } + return FPF_SKIACHARSET_Default; } -static FX_DWORD FPF_SKIAGetFamilyHash(const CFX_ByteStringC& bsFamily, FX_DWORD dwStyle, uint8_t uCharset) -{ - CFX_ByteString bsFont(bsFamily); - if (dwStyle & FXFONT_BOLD) { - bsFont += "Bold"; - } - if (dwStyle & FXFONT_ITALIC) { - bsFont += "Italic"; - } - if (dwStyle & FXFONT_SERIF) { - bsFont += "Serif"; - } - bsFont += uCharset; - return FPF_GetHashCode_StringA(bsFont.c_str(), bsFont.GetLength(), TRUE); +static FX_DWORD FPF_SKIANormalizeFontName(const CFX_ByteStringC& bsfamily) { + FX_DWORD dwHash = 0; + int32_t iLength = bsfamily.GetLength(); + const FX_CHAR* pBuffer = bsfamily.GetCStr(); + for (int32_t i = 0; i < iLength; i++) { + FX_CHAR ch = pBuffer[i]; + if (ch == ' ' || ch == '-' || ch == ',') { + continue; + } + dwHash = 31 * dwHash + FXSYS_tolower(ch); + } + return dwHash; } -static FX_BOOL FPF_SkiaIsCJK(uint8_t uCharset) -{ - return (uCharset == FXFONT_GB2312_CHARSET) || (uCharset == FXFONT_CHINESEBIG5_CHARSET) - || (uCharset == FXFONT_HANGEUL_CHARSET) || (uCharset == FXFONT_SHIFTJIS_CHARSET); +static FX_DWORD FPF_SKIAGetFamilyHash(const CFX_ByteStringC& bsFamily, + FX_DWORD dwStyle, + uint8_t uCharset) { + CFX_ByteString bsFont(bsFamily); + if (dwStyle & FXFONT_BOLD) { + bsFont += "Bold"; + } + if (dwStyle & FXFONT_ITALIC) { + bsFont += "Italic"; + } + if (dwStyle & FXFONT_SERIF) { + bsFont += "Serif"; + } + bsFont += uCharset; + return FPF_GetHashCode_StringA(bsFont.c_str(), bsFont.GetLength(), TRUE); } -static FX_BOOL FPF_SkiaMaybeSymbol(const CFX_ByteStringC& bsFacename) -{ - CFX_ByteString bsName = bsFacename; - bsName.MakeLower(); - return bsName.Find("symbol") > -1; +static FX_BOOL FPF_SkiaIsCJK(uint8_t uCharset) { + return (uCharset == FXFONT_GB2312_CHARSET) || + (uCharset == FXFONT_CHINESEBIG5_CHARSET) || + (uCharset == FXFONT_HANGEUL_CHARSET) || + (uCharset == FXFONT_SHIFTJIS_CHARSET); } -static FX_BOOL FPF_SkiaMaybeArabic(const CFX_ByteStringC& bsFacename) -{ - CFX_ByteString bsName = bsFacename; - bsName.MakeLower(); - return bsName.Find("arabic") > -1; +static FX_BOOL FPF_SkiaMaybeSymbol(const CFX_ByteStringC& bsFacename) { + CFX_ByteString bsName = bsFacename; + bsName.MakeLower(); + return bsName.Find("symbol") > -1; } -CFPF_SkiaFontMgr::CFPF_SkiaFontMgr() - : m_bLoaded(FALSE), m_FTLibrary(NULL) -{ +static FX_BOOL FPF_SkiaMaybeArabic(const CFX_ByteStringC& bsFacename) { + CFX_ByteString bsName = bsFacename; + bsName.MakeLower(); + return bsName.Find("arabic") > -1; } -CFPF_SkiaFontMgr::~CFPF_SkiaFontMgr() -{ - void *pkey = NULL; - CFPF_SkiaFont *pValue = NULL; - FX_POSITION pos = m_FamilyFonts.GetStartPosition(); - while (pos) { - m_FamilyFonts.GetNextAssoc(pos, pkey, (void*&)pValue); - if (pValue) { - pValue->Release(); - } - } - m_FamilyFonts.RemoveAll(); - for (int32_t i = m_FontFaces.GetUpperBound(); i >= 0; i--) { - CFPF_SkiaFontDescriptor *pFont = (CFPF_SkiaFontDescriptor*)m_FontFaces.ElementAt(i); - delete pFont; - } - m_FontFaces.RemoveAll(); - if (m_FTLibrary) { - FXFT_Done_FreeType(m_FTLibrary); - } +CFPF_SkiaFontMgr::CFPF_SkiaFontMgr() : m_bLoaded(FALSE), m_FTLibrary(NULL) {} +CFPF_SkiaFontMgr::~CFPF_SkiaFontMgr() { + void* pkey = NULL; + CFPF_SkiaFont* pValue = NULL; + FX_POSITION pos = m_FamilyFonts.GetStartPosition(); + while (pos) { + m_FamilyFonts.GetNextAssoc(pos, pkey, (void*&)pValue); + if (pValue) { + pValue->Release(); + } + } + m_FamilyFonts.RemoveAll(); + for (int32_t i = m_FontFaces.GetUpperBound(); i >= 0; i--) { + CFPF_SkiaFontDescriptor* pFont = + (CFPF_SkiaFontDescriptor*)m_FontFaces.ElementAt(i); + delete pFont; + } + m_FontFaces.RemoveAll(); + if (m_FTLibrary) { + FXFT_Done_FreeType(m_FTLibrary); + } } -FX_BOOL CFPF_SkiaFontMgr::InitFTLibrary() -{ - if (m_FTLibrary == NULL) { - FXFT_Init_FreeType(&m_FTLibrary); - } - return m_FTLibrary != NULL; +FX_BOOL CFPF_SkiaFontMgr::InitFTLibrary() { + if (m_FTLibrary == NULL) { + FXFT_Init_FreeType(&m_FTLibrary); + } + return m_FTLibrary != NULL; } -void CFPF_SkiaFontMgr::LoadSystemFonts() -{ - if (m_bLoaded) { - return; - } - ScanPath(FX_BSTRC("/system/fonts")); - OutputSystemFonts(); - m_bLoaded = TRUE; -} -void CFPF_SkiaFontMgr::LoadPrivateFont(IFX_FileRead* pFontFile) -{ +void CFPF_SkiaFontMgr::LoadSystemFonts() { + if (m_bLoaded) { + return; + } + ScanPath(FX_BSTRC("/system/fonts")); + OutputSystemFonts(); + m_bLoaded = TRUE; } -void CFPF_SkiaFontMgr::LoadPrivateFont(const CFX_ByteStringC& bsFileName) -{ +void CFPF_SkiaFontMgr::LoadPrivateFont(IFX_FileRead* pFontFile) {} +void CFPF_SkiaFontMgr::LoadPrivateFont(const CFX_ByteStringC& bsFileName) {} +void CFPF_SkiaFontMgr::LoadPrivateFont(void* pBuffer, size_t szBuffer) {} +IFPF_Font* CFPF_SkiaFontMgr::CreateFont(const CFX_ByteStringC& bsFamilyname, + uint8_t uCharset, + FX_DWORD dwStyle, + FX_DWORD dwMatch) { + FX_DWORD dwHash = FPF_SKIAGetFamilyHash(bsFamilyname, dwStyle, uCharset); + IFPF_Font* pFont = NULL; + if (m_FamilyFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont)) { + if (pFont) { + return pFont->Retain(); + } + } + FX_DWORD dwFaceName = FPF_SKIANormalizeFontName(bsFamilyname); + FX_DWORD dwSubst = FPF_SkiaGetSubstFont(dwFaceName); + FX_DWORD dwSubstSans = FPF_SkiaGetSansFont(dwFaceName); + FX_BOOL bMaybeSymbol = FPF_SkiaMaybeSymbol(bsFamilyname); + if (uCharset != FXFONT_ARABIC_CHARSET && FPF_SkiaMaybeArabic(bsFamilyname)) { + uCharset = FXFONT_ARABIC_CHARSET; + } else if (uCharset == FXFONT_ANSI_CHARSET && + (dwMatch & FPF_MATCHFONT_REPLACEANSI)) { + uCharset = FXFONT_DEFAULT_CHARSET; + } + int32_t nExpectVal = FPF_SKIAMATCHWEIGHT_NAME1 + FPF_SKIAMATCHWEIGHT_1 * 3 + + FPF_SKIAMATCHWEIGHT_2 * 2; + int32_t nItem = -1; + int32_t nMax = -1; + int32_t nGlyphNum = 0; + for (int32_t i = m_FontFaces.GetUpperBound(); i >= 0; i--) { + CFPF_SkiaPathFont* pFontDes = (CFPF_SkiaPathFont*)m_FontFaces.ElementAt(i); + if (!(pFontDes->m_dwCharsets & FPF_SkiaGetCharset(uCharset))) { + continue; + } + int32_t nFind = 0; + FX_DWORD dwSysFontName = FPF_SKIANormalizeFontName(pFontDes->m_pFamily); + if (dwFaceName == dwSysFontName) { + nFind += FPF_SKIAMATCHWEIGHT_NAME1; + } + FX_BOOL bMatchedName = (nFind == FPF_SKIAMATCHWEIGHT_NAME1); + if ((dwStyle & FXFONT_BOLD) == (pFontDes->m_dwStyle & FXFONT_BOLD)) { + nFind += FPF_SKIAMATCHWEIGHT_1; + } + if ((dwStyle & FXFONT_ITALIC) == (pFontDes->m_dwStyle & FXFONT_ITALIC)) { + nFind += FPF_SKIAMATCHWEIGHT_1; + } + if ((dwStyle & FXFONT_FIXED_PITCH) == + (pFontDes->m_dwStyle & FXFONT_FIXED_PITCH)) { + nFind += FPF_SKIAMATCHWEIGHT_2; + } + if ((dwStyle & FXFONT_SERIF) == (pFontDes->m_dwStyle & FXFONT_SERIF)) { + nFind += FPF_SKIAMATCHWEIGHT_1; + } + if ((dwStyle & FXFONT_SCRIPT) == (pFontDes->m_dwStyle & FXFONT_SCRIPT)) { + nFind += FPF_SKIAMATCHWEIGHT_2; + } + if (dwSubst == dwSysFontName || dwSubstSans == dwSysFontName) { + nFind += FPF_SKIAMATCHWEIGHT_NAME2; + bMatchedName = TRUE; + } + if (uCharset == FXFONT_DEFAULT_CHARSET || bMaybeSymbol) { + if (nFind > nMax && bMatchedName) { + nMax = nFind; + nItem = i; + } + } else if (FPF_SkiaIsCJK(uCharset)) { + if (bMatchedName || pFontDes->m_iGlyphNum > nGlyphNum) { + nItem = i; + nGlyphNum = pFontDes->m_iGlyphNum; + } + } else if (nFind > nMax) { + nMax = nFind; + nItem = i; + } + if (nExpectVal <= nFind) { + nItem = i; + break; + } + } + if (nItem > -1) { + CFPF_SkiaFontDescriptor* pFontDes = + (CFPF_SkiaFontDescriptor*)m_FontFaces.ElementAt(nItem); + CFPF_SkiaFont* pFont = new CFPF_SkiaFont; + if (pFont->InitFont(this, pFontDes, bsFamilyname, dwStyle, uCharset)) { + m_FamilyFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont); + return pFont->Retain(); + } + pFont->Release(); + } + return NULL; } -void CFPF_SkiaFontMgr::LoadPrivateFont(void* pBuffer, size_t szBuffer) -{ -} -IFPF_Font* CFPF_SkiaFontMgr::CreateFont(const CFX_ByteStringC& bsFamilyname, uint8_t uCharset, FX_DWORD dwStyle, FX_DWORD dwMatch) -{ - FX_DWORD dwHash = FPF_SKIAGetFamilyHash(bsFamilyname, dwStyle, uCharset); - IFPF_Font *pFont = NULL; - if (m_FamilyFonts.Lookup((void*)(uintptr_t)dwHash, (void*&)pFont)) { - if (pFont) { - return pFont->Retain(); - } - } - FX_DWORD dwFaceName = FPF_SKIANormalizeFontName(bsFamilyname); - FX_DWORD dwSubst = FPF_SkiaGetSubstFont(dwFaceName); - FX_DWORD dwSubstSans = FPF_SkiaGetSansFont(dwFaceName); - FX_BOOL bMaybeSymbol = FPF_SkiaMaybeSymbol(bsFamilyname); - if (uCharset != FXFONT_ARABIC_CHARSET && FPF_SkiaMaybeArabic(bsFamilyname)) { - uCharset = FXFONT_ARABIC_CHARSET; - } else if (uCharset == FXFONT_ANSI_CHARSET && (dwMatch & FPF_MATCHFONT_REPLACEANSI)) { - uCharset = FXFONT_DEFAULT_CHARSET; - } - int32_t nExpectVal = FPF_SKIAMATCHWEIGHT_NAME1 + FPF_SKIAMATCHWEIGHT_1 * 3 + FPF_SKIAMATCHWEIGHT_2 * 2; - int32_t nItem = -1; - int32_t nMax = -1; - int32_t nGlyphNum = 0; - for (int32_t i = m_FontFaces.GetUpperBound(); i >= 0; i--) { - CFPF_SkiaPathFont *pFontDes = (CFPF_SkiaPathFont*)m_FontFaces.ElementAt(i); - if(!(pFontDes->m_dwCharsets & FPF_SkiaGetCharset(uCharset))) { - continue; - } - int32_t nFind = 0; - FX_DWORD dwSysFontName = FPF_SKIANormalizeFontName(pFontDes->m_pFamily); - if (dwFaceName == dwSysFontName) { - nFind += FPF_SKIAMATCHWEIGHT_NAME1; - } - FX_BOOL bMatchedName = (nFind == FPF_SKIAMATCHWEIGHT_NAME1); - if ((dwStyle & FXFONT_BOLD) == (pFontDes->m_dwStyle & FXFONT_BOLD)) { - nFind += FPF_SKIAMATCHWEIGHT_1; - } - if ((dwStyle & FXFONT_ITALIC) == (pFontDes->m_dwStyle & FXFONT_ITALIC)) { - nFind += FPF_SKIAMATCHWEIGHT_1; - } - if ((dwStyle & FXFONT_FIXED_PITCH) == (pFontDes->m_dwStyle & FXFONT_FIXED_PITCH)) { - nFind += FPF_SKIAMATCHWEIGHT_2; - } - if ((dwStyle & FXFONT_SERIF) == (pFontDes->m_dwStyle & FXFONT_SERIF)) { - nFind += FPF_SKIAMATCHWEIGHT_1; - } - if ((dwStyle & FXFONT_SCRIPT) == (pFontDes->m_dwStyle & FXFONT_SCRIPT)) { - nFind += FPF_SKIAMATCHWEIGHT_2; - } - if (dwSubst == dwSysFontName || dwSubstSans == dwSysFontName) { - nFind += FPF_SKIAMATCHWEIGHT_NAME2; - bMatchedName = TRUE; - } - if (uCharset == FXFONT_DEFAULT_CHARSET || bMaybeSymbol) { - if (nFind > nMax && bMatchedName) { - nMax = nFind; - nItem = i; - } - } else if (FPF_SkiaIsCJK(uCharset)) { - if (bMatchedName || pFontDes->m_iGlyphNum > nGlyphNum) { - nItem = i; - nGlyphNum = pFontDes->m_iGlyphNum; - } - } else if (nFind > nMax) { - nMax = nFind; - nItem = i; - } - if (nExpectVal <= nFind) { - nItem = i; - break; - } - } - if (nItem > -1) { - CFPF_SkiaFontDescriptor *pFontDes = (CFPF_SkiaFontDescriptor*)m_FontFaces.ElementAt(nItem); - CFPF_SkiaFont *pFont = new CFPF_SkiaFont; - if (pFont->InitFont(this, pFontDes, bsFamilyname, dwStyle, uCharset)) { - m_FamilyFonts.SetAt((void*)(uintptr_t)dwHash, (void*)pFont); - return pFont->Retain(); - } - pFont->Release(); - } +FXFT_Face CFPF_SkiaFontMgr::GetFontFace(IFX_FileRead* pFileRead, + int32_t iFaceIndex) { + if (!pFileRead) { return NULL; + } + if (pFileRead->GetSize() == 0) { + return NULL; + } + if (iFaceIndex < 0) { + return NULL; + } + FXFT_StreamRec streamRec; + FXSYS_memset(&streamRec, 0, sizeof(FXFT_StreamRec)); + streamRec.size = pFileRead->GetSize(); + streamRec.descriptor.pointer = pFileRead; + streamRec.read = FPF_SkiaStream_Read; + streamRec.close = FPF_SkiaStream_Close; + FXFT_Open_Args args; + args.flags = FT_OPEN_STREAM; + args.stream = &streamRec; + FXFT_Face face; + if (FXFT_Open_Face(m_FTLibrary, &args, iFaceIndex, &face)) { + return NULL; + } + FXFT_Set_Pixel_Sizes(face, 0, 64); + return face; } -FXFT_Face CFPF_SkiaFontMgr::GetFontFace(IFX_FileRead *pFileRead, int32_t iFaceIndex) -{ - if (!pFileRead) { - return NULL; - } - if (pFileRead->GetSize() == 0) { - return NULL; - } - if (iFaceIndex < 0) { - return NULL; - } - FXFT_StreamRec streamRec; - FXSYS_memset(&streamRec, 0, sizeof(FXFT_StreamRec)); - streamRec.size = pFileRead->GetSize(); - streamRec.descriptor.pointer = pFileRead; - streamRec.read = FPF_SkiaStream_Read; - streamRec.close = FPF_SkiaStream_Close; - FXFT_Open_Args args; - args.flags = FT_OPEN_STREAM; - args.stream = &streamRec; - FXFT_Face face; - if (FXFT_Open_Face(m_FTLibrary, &args, iFaceIndex, &face)) { - return NULL; - } - FXFT_Set_Pixel_Sizes(face, 0, 64); - return face; -} -FXFT_Face CFPF_SkiaFontMgr::GetFontFace(const CFX_ByteStringC& bsFile, int32_t iFaceIndex ) -{ - if (bsFile.IsEmpty()) { - return NULL; - } - if (iFaceIndex < 0) { - return NULL; - } - FXFT_Open_Args args; - args.flags = FT_OPEN_PATHNAME; - args.pathname = (FT_String*)bsFile.GetCStr(); - FXFT_Face face; - if (FXFT_Open_Face(m_FTLibrary, &args, iFaceIndex, &face)) { - return FALSE; - } - FXFT_Set_Pixel_Sizes(face, 0, 64); - return face; +FXFT_Face CFPF_SkiaFontMgr::GetFontFace(const CFX_ByteStringC& bsFile, + int32_t iFaceIndex) { + if (bsFile.IsEmpty()) { + return NULL; + } + if (iFaceIndex < 0) { + return NULL; + } + FXFT_Open_Args args; + args.flags = FT_OPEN_PATHNAME; + args.pathname = (FT_String*)bsFile.GetCStr(); + FXFT_Face face; + if (FXFT_Open_Face(m_FTLibrary, &args, iFaceIndex, &face)) { + return FALSE; + } + FXFT_Set_Pixel_Sizes(face, 0, 64); + return face; } -FXFT_Face CFPF_SkiaFontMgr::GetFontFace(const uint8_t* pBuffer, size_t szBuffer, int32_t iFaceIndex ) -{ - if (!pBuffer || szBuffer < 1) { - return NULL; - } - if (iFaceIndex < 0) { - return NULL; - } - FXFT_Open_Args args; - args.flags = FT_OPEN_MEMORY; - args.memory_base = pBuffer; - args.memory_size = szBuffer; - FXFT_Face face; - if (FXFT_Open_Face(m_FTLibrary, &args, iFaceIndex, &face)) { - return FALSE; - } - FXFT_Set_Pixel_Sizes(face, 0, 64); - return face; +FXFT_Face CFPF_SkiaFontMgr::GetFontFace(const uint8_t* pBuffer, + size_t szBuffer, + int32_t iFaceIndex) { + if (!pBuffer || szBuffer < 1) { + return NULL; + } + if (iFaceIndex < 0) { + return NULL; + } + FXFT_Open_Args args; + args.flags = FT_OPEN_MEMORY; + args.memory_base = pBuffer; + args.memory_size = szBuffer; + FXFT_Face face; + if (FXFT_Open_Face(m_FTLibrary, &args, iFaceIndex, &face)) { + return FALSE; + } + FXFT_Set_Pixel_Sizes(face, 0, 64); + return face; } -void CFPF_SkiaFontMgr::ScanPath(const CFX_ByteStringC& path) -{ - void *handle = FX_OpenFolder(path.GetCStr()); - if (!handle) { - return; - } - CFX_ByteString filename; - FX_BOOL bFolder = FALSE; - while (FX_GetNextFile(handle, filename, bFolder)) { - if (bFolder) { - if (filename == FX_BSTRC(".") || filename == FX_BSTRC("..")) { - continue; - } - } else { - CFX_ByteString ext = filename.Right(4); - ext.MakeLower(); - if (ext != FX_BSTRC(".ttf") && ext != FX_BSTRC(".ttc")) { - continue; - } - } - CFX_ByteString fullpath = path; - fullpath += "/"; - fullpath += filename; - if (bFolder) { - ScanPath(fullpath); - } else { - ScanFile(fullpath); - } +void CFPF_SkiaFontMgr::ScanPath(const CFX_ByteStringC& path) { + void* handle = FX_OpenFolder(path.GetCStr()); + if (!handle) { + return; + } + CFX_ByteString filename; + FX_BOOL bFolder = FALSE; + while (FX_GetNextFile(handle, filename, bFolder)) { + if (bFolder) { + if (filename == FX_BSTRC(".") || filename == FX_BSTRC("..")) { + continue; + } + } else { + CFX_ByteString ext = filename.Right(4); + ext.MakeLower(); + if (ext != FX_BSTRC(".ttf") && ext != FX_BSTRC(".ttc")) { + continue; + } + } + CFX_ByteString fullpath = path; + fullpath += "/"; + fullpath += filename; + if (bFolder) { + ScanPath(fullpath); + } else { + ScanFile(fullpath); } - FX_CloseFolder(handle); + } + FX_CloseFolder(handle); } -void CFPF_SkiaFontMgr::ScanFile(const CFX_ByteStringC& file) -{ - FXFT_Face face = GetFontFace(file); - if (face) { - CFPF_SkiaPathFont *pFontDesc = new CFPF_SkiaPathFont; - pFontDesc->SetPath(file.GetCStr()); - ReportFace(face, pFontDesc); - m_FontFaces.Add(pFontDesc); - FXFT_Done_Face(face); - } +void CFPF_SkiaFontMgr::ScanFile(const CFX_ByteStringC& file) { + FXFT_Face face = GetFontFace(file); + if (face) { + CFPF_SkiaPathFont* pFontDesc = new CFPF_SkiaPathFont; + pFontDesc->SetPath(file.GetCStr()); + ReportFace(face, pFontDesc); + m_FontFaces.Add(pFontDesc); + FXFT_Done_Face(face); + } } -static const FX_DWORD g_FPFSkiaFontCharsets [] = { +static const FX_DWORD g_FPFSkiaFontCharsets[] = { FPF_SKIACHARSET_Ansi, FPF_SKIACHARSET_EeasternEuropean, FPF_SKIACHARSET_Cyrillic, @@ -499,54 +479,51 @@ static const FX_DWORD g_FPFSkiaFontCharsets [] = { FPF_SKIACHARSET_OEM, FPF_SKIACHARSET_Symbol, }; -static FX_DWORD FPF_SkiaGetFaceCharset(TT_OS2 *pOS2) -{ - FX_DWORD dwCharset = 0; - if (pOS2) { - for (int32_t i = 0; i < 32; i++) { - if (pOS2->ulCodePageRange1 & (1 << i)) { - dwCharset |= g_FPFSkiaFontCharsets[i]; - } - } - } - dwCharset |= FPF_SKIACHARSET_Default; - return dwCharset; -} -void CFPF_SkiaFontMgr::ReportFace(FXFT_Face face, CFPF_SkiaFontDescriptor *pFontDesc) -{ - if (!face || !pFontDesc) { - return; - } - pFontDesc->SetFamily(FXFT_Get_Face_Family_Name(face)); - if (FXFT_Is_Face_Bold(face)) { - pFontDesc->m_dwStyle |= FXFONT_BOLD; - } - if (FXFT_Is_Face_Italic(face)) { - pFontDesc->m_dwStyle |= FXFONT_ITALIC; - } - if (FT_IS_FIXED_WIDTH(face)) { - pFontDesc->m_dwStyle |= FXFONT_FIXED_PITCH; - } - TT_OS2 *pOS2 = (TT_OS2*)FT_Get_Sfnt_Table(face, ft_sfnt_os2); - if (pOS2) { - if (pOS2->ulCodePageRange1 & (1 << 31)) { - pFontDesc->m_dwStyle |= FXFONT_SYMBOLIC; - } - if (pOS2->panose[0] == 2) { - uint8_t uSerif = pOS2->panose[1]; - if ((uSerif > 1 && uSerif < 10) || uSerif > 13) { - pFontDesc->m_dwStyle |= FXFONT_SERIF; - } - } - } - if (pOS2 && (pOS2->ulCodePageRange1 & (1 << 31))) { - pFontDesc->m_dwStyle |= FXFONT_SYMBOLIC; - } - pFontDesc->m_dwCharsets = FPF_SkiaGetFaceCharset(pOS2); - pFontDesc->m_iFaceIndex = face->face_index; - pFontDesc->m_iGlyphNum = face->num_glyphs; +static FX_DWORD FPF_SkiaGetFaceCharset(TT_OS2* pOS2) { + FX_DWORD dwCharset = 0; + if (pOS2) { + for (int32_t i = 0; i < 32; i++) { + if (pOS2->ulCodePageRange1 & (1 << i)) { + dwCharset |= g_FPFSkiaFontCharsets[i]; + } + } + } + dwCharset |= FPF_SKIACHARSET_Default; + return dwCharset; } -void CFPF_SkiaFontMgr::OutputSystemFonts() -{ +void CFPF_SkiaFontMgr::ReportFace(FXFT_Face face, + CFPF_SkiaFontDescriptor* pFontDesc) { + if (!face || !pFontDesc) { + return; + } + pFontDesc->SetFamily(FXFT_Get_Face_Family_Name(face)); + if (FXFT_Is_Face_Bold(face)) { + pFontDesc->m_dwStyle |= FXFONT_BOLD; + } + if (FXFT_Is_Face_Italic(face)) { + pFontDesc->m_dwStyle |= FXFONT_ITALIC; + } + if (FT_IS_FIXED_WIDTH(face)) { + pFontDesc->m_dwStyle |= FXFONT_FIXED_PITCH; + } + TT_OS2* pOS2 = (TT_OS2*)FT_Get_Sfnt_Table(face, ft_sfnt_os2); + if (pOS2) { + if (pOS2->ulCodePageRange1 & (1 << 31)) { + pFontDesc->m_dwStyle |= FXFONT_SYMBOLIC; + } + if (pOS2->panose[0] == 2) { + uint8_t uSerif = pOS2->panose[1]; + if ((uSerif > 1 && uSerif < 10) || uSerif > 13) { + pFontDesc->m_dwStyle |= FXFONT_SERIF; + } + } + } + if (pOS2 && (pOS2->ulCodePageRange1 & (1 << 31))) { + pFontDesc->m_dwStyle |= FXFONT_SYMBOLIC; + } + pFontDesc->m_dwCharsets = FPF_SkiaGetFaceCharset(pOS2); + pFontDesc->m_iFaceIndex = face->face_index; + pFontDesc->m_iGlyphNum = face->num_glyphs; } +void CFPF_SkiaFontMgr::OutputSystemFonts() {} #endif diff --git a/core/src/fxge/android/fpf_skiafontmgr.h b/core/src/fxge/android/fpf_skiafontmgr.h index 8c721ff68a..c5dd8fd1b2 100644 --- a/core/src/fxge/android/fpf_skiafontmgr.h +++ b/core/src/fxge/android/fpf_skiafontmgr.h @@ -8,111 +8,101 @@ #define CORE_SRC_FXGE_ANDROID_FPF_SKIAFONTMGR_H_ #if _FX_OS_ == _FX_ANDROID_ -#define FPF_SKIAFONTTYPE_Unknown 0 -#define FPF_SKIAFONTTYPE_Path 1 -#define FPF_SKIAFONTTYPE_File 2 -#define FPF_SKIAFONTTYPE_Buffer 3 -class CFPF_SkiaFontDescriptor -{ -public: - CFPF_SkiaFontDescriptor() : m_pFamily(NULL), m_dwStyle(0), m_iFaceIndex(0), m_dwCharsets(0), m_iGlyphNum(0) {} - virtual ~CFPF_SkiaFontDescriptor() - { - if (m_pFamily) { - FX_Free(m_pFamily); - } +#define FPF_SKIAFONTTYPE_Unknown 0 +#define FPF_SKIAFONTTYPE_Path 1 +#define FPF_SKIAFONTTYPE_File 2 +#define FPF_SKIAFONTTYPE_Buffer 3 +class CFPF_SkiaFontDescriptor { + public: + CFPF_SkiaFontDescriptor() + : m_pFamily(NULL), + m_dwStyle(0), + m_iFaceIndex(0), + m_dwCharsets(0), + m_iGlyphNum(0) {} + virtual ~CFPF_SkiaFontDescriptor() { + if (m_pFamily) { + FX_Free(m_pFamily); } - virtual int32_t GetType() const - { - return FPF_SKIAFONTTYPE_Unknown; + } + virtual int32_t GetType() const { return FPF_SKIAFONTTYPE_Unknown; } + void SetFamily(const FX_CHAR* pFamily) { + if (m_pFamily) { + FX_Free(m_pFamily); } - void SetFamily(const FX_CHAR* pFamily) - { - if (m_pFamily) { - FX_Free(m_pFamily); - } - int32_t iSize = FXSYS_strlen(pFamily); - m_pFamily = FX_Alloc(FX_CHAR, iSize + 1); - FXSYS_memcpy(m_pFamily, pFamily, iSize * sizeof(FX_CHAR)); - m_pFamily[iSize] = 0; - } - FX_CHAR* m_pFamily; - FX_DWORD m_dwStyle; - int32_t m_iFaceIndex; - FX_DWORD m_dwCharsets; - int32_t m_iGlyphNum; + int32_t iSize = FXSYS_strlen(pFamily); + m_pFamily = FX_Alloc(FX_CHAR, iSize + 1); + FXSYS_memcpy(m_pFamily, pFamily, iSize * sizeof(FX_CHAR)); + m_pFamily[iSize] = 0; + } + FX_CHAR* m_pFamily; + FX_DWORD m_dwStyle; + int32_t m_iFaceIndex; + FX_DWORD m_dwCharsets; + int32_t m_iGlyphNum; }; -class CFPF_SkiaPathFont : public CFPF_SkiaFontDescriptor -{ -public: - CFPF_SkiaPathFont() : m_pPath(NULL) {} - virtual ~CFPF_SkiaPathFont() - { - if (m_pPath) { - FX_Free(m_pPath); - } - } - virtual int32_t GetType() const - { - return FPF_SKIAFONTTYPE_Path; +class CFPF_SkiaPathFont : public CFPF_SkiaFontDescriptor { + public: + CFPF_SkiaPathFont() : m_pPath(NULL) {} + virtual ~CFPF_SkiaPathFont() { + if (m_pPath) { + FX_Free(m_pPath); } - void SetPath(const FX_CHAR* pPath) - { - if (m_pPath) { - FX_Free(m_pPath); - } - int32_t iSize = FXSYS_strlen(pPath); - m_pPath = FX_Alloc(FX_CHAR, iSize + 1); - FXSYS_memcpy(m_pPath, pPath, iSize * sizeof(FX_CHAR)); - m_pPath[iSize] = 0; + } + virtual int32_t GetType() const { return FPF_SKIAFONTTYPE_Path; } + void SetPath(const FX_CHAR* pPath) { + if (m_pPath) { + FX_Free(m_pPath); } - FX_CHAR* m_pPath; + int32_t iSize = FXSYS_strlen(pPath); + m_pPath = FX_Alloc(FX_CHAR, iSize + 1); + FXSYS_memcpy(m_pPath, pPath, iSize * sizeof(FX_CHAR)); + m_pPath[iSize] = 0; + } + FX_CHAR* m_pPath; }; -class CFPF_SkiaFileFont : public CFPF_SkiaFontDescriptor -{ -public: - CFPF_SkiaFileFont() : m_pFile(NULL) {} - virtual int32_t GetType() const - { - return FPF_SKIAFONTTYPE_File; - } - IFX_FileRead *m_pFile; +class CFPF_SkiaFileFont : public CFPF_SkiaFontDescriptor { + public: + CFPF_SkiaFileFont() : m_pFile(NULL) {} + virtual int32_t GetType() const { return FPF_SKIAFONTTYPE_File; } + IFX_FileRead* m_pFile; }; -class CFPF_SkiaBufferFont : public CFPF_SkiaFontDescriptor -{ -public: - CFPF_SkiaBufferFont() : m_pBuffer(NULL), m_szBuffer(0) {} - virtual int32_t GetType() const - { - return FPF_SKIAFONTTYPE_Buffer; - } - void* m_pBuffer; - size_t m_szBuffer; +class CFPF_SkiaBufferFont : public CFPF_SkiaFontDescriptor { + public: + CFPF_SkiaBufferFont() : m_pBuffer(NULL), m_szBuffer(0) {} + virtual int32_t GetType() const { return FPF_SKIAFONTTYPE_Buffer; } + void* m_pBuffer; + size_t m_szBuffer; }; -class CFPF_SkiaFontMgr : public IFPF_FontMgr -{ -public: - CFPF_SkiaFontMgr(); - virtual ~CFPF_SkiaFontMgr(); - FX_BOOL InitFTLibrary(); - virtual void LoadSystemFonts(); - virtual void LoadPrivateFont(IFX_FileRead* pFontFile); - virtual void LoadPrivateFont(const CFX_ByteStringC& bsFileName); - virtual void LoadPrivateFont(void* pBuffer, size_t szBuffer); +class CFPF_SkiaFontMgr : public IFPF_FontMgr { + public: + CFPF_SkiaFontMgr(); + virtual ~CFPF_SkiaFontMgr(); + FX_BOOL InitFTLibrary(); + virtual void LoadSystemFonts(); + virtual void LoadPrivateFont(IFX_FileRead* pFontFile); + virtual void LoadPrivateFont(const CFX_ByteStringC& bsFileName); + virtual void LoadPrivateFont(void* pBuffer, size_t szBuffer); + + virtual IFPF_Font* CreateFont(const CFX_ByteStringC& bsFamilyname, + uint8_t uCharset, + FX_DWORD dwStyle, + FX_DWORD dwMatch = 0); + FXFT_Face GetFontFace(IFX_FileRead* pFileRead, int32_t iFaceIndex = 0); + FXFT_Face GetFontFace(const CFX_ByteStringC& bsFile, int32_t iFaceIndex = 0); + FXFT_Face GetFontFace(const uint8_t* pBuffer, + size_t szBuffer, + int32_t iFaceIndex = 0); - virtual IFPF_Font* CreateFont(const CFX_ByteStringC& bsFamilyname, uint8_t uCharset, FX_DWORD dwStyle, FX_DWORD dwMatch = 0); - FXFT_Face GetFontFace(IFX_FileRead *pFileRead, int32_t iFaceIndex = 0); - FXFT_Face GetFontFace(const CFX_ByteStringC& bsFile, int32_t iFaceIndex = 0); - FXFT_Face GetFontFace(const uint8_t* pBuffer, size_t szBuffer, int32_t iFaceIndex = 0); -protected: - void ScanPath(const CFX_ByteStringC& path); - void ScanFile(const CFX_ByteStringC& file); - void ReportFace(FXFT_Face face, CFPF_SkiaFontDescriptor *pFontDesc); - void OutputSystemFonts(); - FX_BOOL m_bLoaded; - CFX_PtrArray m_FontFaces; - FXFT_Library m_FTLibrary; - CFX_MapPtrToPtr m_FamilyFonts; + protected: + void ScanPath(const CFX_ByteStringC& path); + void ScanFile(const CFX_ByteStringC& file); + void ReportFace(FXFT_Face face, CFPF_SkiaFontDescriptor* pFontDesc); + void OutputSystemFonts(); + FX_BOOL m_bLoaded; + CFX_PtrArray m_FontFaces; + FXFT_Library m_FTLibrary; + CFX_MapPtrToPtr m_FamilyFonts; }; #endif diff --git a/core/src/fxge/android/fpf_skiamodule.cpp b/core/src/fxge/android/fpf_skiamodule.cpp index 296073c4e2..fdc3398d30 100644 --- a/core/src/fxge/android/fpf_skiamodule.cpp +++ b/core/src/fxge/android/fpf_skiamodule.cpp @@ -8,32 +8,28 @@ #if _FX_OS_ == _FX_ANDROID_ #include "fpf_skiamodule.h" #include "fpf_skiafontmgr.h" -static IFPF_DeviceModule *gs_pPFModule = NULL; -IFPF_DeviceModule* FPF_GetDeviceModule() -{ - if (!gs_pPFModule) { - gs_pPFModule = new CFPF_SkiaDeviceModule; - } - return gs_pPFModule; +static IFPF_DeviceModule* gs_pPFModule = NULL; +IFPF_DeviceModule* FPF_GetDeviceModule() { + if (!gs_pPFModule) { + gs_pPFModule = new CFPF_SkiaDeviceModule; + } + return gs_pPFModule; } -CFPF_SkiaDeviceModule::~CFPF_SkiaDeviceModule() -{ - delete m_pFontMgr; +CFPF_SkiaDeviceModule::~CFPF_SkiaDeviceModule() { + delete m_pFontMgr; } -void CFPF_SkiaDeviceModule::Destroy() -{ - delete (CFPF_SkiaDeviceModule*)gs_pPFModule; - gs_pPFModule = NULL; +void CFPF_SkiaDeviceModule::Destroy() { + delete (CFPF_SkiaDeviceModule*)gs_pPFModule; + gs_pPFModule = NULL; } -IFPF_FontMgr* CFPF_SkiaDeviceModule::GetFontMgr() -{ - if (!m_pFontMgr) { - m_pFontMgr = new CFPF_SkiaFontMgr; - if (!m_pFontMgr->InitFTLibrary()) { - delete m_pFontMgr; - return NULL; - } +IFPF_FontMgr* CFPF_SkiaDeviceModule::GetFontMgr() { + if (!m_pFontMgr) { + m_pFontMgr = new CFPF_SkiaFontMgr; + if (!m_pFontMgr->InitFTLibrary()) { + delete m_pFontMgr; + return NULL; } - return (IFPF_FontMgr*)m_pFontMgr; + } + return (IFPF_FontMgr*)m_pFontMgr; } #endif diff --git a/core/src/fxge/android/fpf_skiamodule.h b/core/src/fxge/android/fpf_skiamodule.h index 4f0b16ca66..4f1c1193d8 100644 --- a/core/src/fxge/android/fpf_skiamodule.h +++ b/core/src/fxge/android/fpf_skiamodule.h @@ -9,15 +9,15 @@ #if _FX_OS_ == _FX_ANDROID_ class CFPF_SkiaFontMgr; -class CFPF_SkiaDeviceModule : public IFPF_DeviceModule -{ -public: - CFPF_SkiaDeviceModule() : m_pFontMgr(NULL) {} - virtual ~CFPF_SkiaDeviceModule(); - virtual void Destroy(); - virtual IFPF_FontMgr* GetFontMgr(); -protected: - CFPF_SkiaFontMgr *m_pFontMgr; +class CFPF_SkiaDeviceModule : public IFPF_DeviceModule { + public: + CFPF_SkiaDeviceModule() : m_pFontMgr(NULL) {} + virtual ~CFPF_SkiaDeviceModule(); + virtual void Destroy(); + virtual IFPF_FontMgr* GetFontMgr(); + + protected: + CFPF_SkiaFontMgr* m_pFontMgr; }; #endif diff --git a/core/src/fxge/android/fx_android_font.cpp b/core/src/fxge/android/fx_android_font.cpp index fd72e47478..f4dfc290a3 100644 --- a/core/src/fxge/android/fx_android_font.cpp +++ b/core/src/fxge/android/fx_android_font.cpp @@ -6,82 +6,79 @@ #include "fx_fpf.h" #if _FX_OS_ == _FX_ANDROID_ -CFX_AndroidFontInfo::CFX_AndroidFontInfo() - : m_pFontMgr(NULL) -{ -} -FX_BOOL CFX_AndroidFontInfo::Init(IFPF_FontMgr *pFontMgr) -{ - if (!pFontMgr) { - return FALSE; - } - pFontMgr->LoadSystemFonts(); - m_pFontMgr = pFontMgr; - return TRUE; -} -FX_BOOL CFX_AndroidFontInfo::EnumFontList(CFX_FontMapper* pMapper) -{ +CFX_AndroidFontInfo::CFX_AndroidFontInfo() : m_pFontMgr(NULL) {} +FX_BOOL CFX_AndroidFontInfo::Init(IFPF_FontMgr* pFontMgr) { + if (!pFontMgr) { return FALSE; + } + pFontMgr->LoadSystemFonts(); + m_pFontMgr = pFontMgr; + return TRUE; } -void* CFX_AndroidFontInfo::MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, const FX_CHAR* face, int& iExact) -{ - if (!m_pFontMgr) { - return NULL; - } - FX_DWORD dwStyle = 0; - if (weight >= 700) { - dwStyle |= FXFONT_BOLD; - } - if (bItalic) { - dwStyle |= FXFONT_ITALIC; - } - if (pitch_family & FXFONT_FF_FIXEDPITCH) { - dwStyle |= FXFONT_FIXED_PITCH; - } - if (pitch_family & FXFONT_FF_SCRIPT) { - dwStyle |= FXFONT_SCRIPT; - } - if (pitch_family & FXFONT_FF_ROMAN) { - dwStyle |= FXFONT_SERIF; - } - return m_pFontMgr->CreateFont(face, charset, dwStyle, FPF_MATCHFONT_REPLACEANSI); +FX_BOOL CFX_AndroidFontInfo::EnumFontList(CFX_FontMapper* pMapper) { + return FALSE; } -void* CFX_AndroidFontInfo::GetFont(const FX_CHAR* face) -{ +void* CFX_AndroidFontInfo::MapFont(int weight, + FX_BOOL bItalic, + int charset, + int pitch_family, + const FX_CHAR* face, + int& iExact) { + if (!m_pFontMgr) { return NULL; + } + FX_DWORD dwStyle = 0; + if (weight >= 700) { + dwStyle |= FXFONT_BOLD; + } + if (bItalic) { + dwStyle |= FXFONT_ITALIC; + } + if (pitch_family & FXFONT_FF_FIXEDPITCH) { + dwStyle |= FXFONT_FIXED_PITCH; + } + if (pitch_family & FXFONT_FF_SCRIPT) { + dwStyle |= FXFONT_SCRIPT; + } + if (pitch_family & FXFONT_FF_ROMAN) { + dwStyle |= FXFONT_SERIF; + } + return m_pFontMgr->CreateFont(face, charset, dwStyle, + FPF_MATCHFONT_REPLACEANSI); } -FX_DWORD CFX_AndroidFontInfo::GetFontData(void* hFont, FX_DWORD table, uint8_t* buffer, FX_DWORD size) -{ - if (!hFont) { - return 0; - } - return ((IFPF_Font*)hFont)->GetFontData(table, buffer, size); +void* CFX_AndroidFontInfo::GetFont(const FX_CHAR* face) { + return NULL; } -FX_BOOL CFX_AndroidFontInfo::GetFaceName(void* hFont, CFX_ByteString& name) -{ - if (!hFont) { - return FALSE; - } - name = ((IFPF_Font*)hFont)->GetFamilyName(); - return TRUE; +FX_DWORD CFX_AndroidFontInfo::GetFontData(void* hFont, + FX_DWORD table, + uint8_t* buffer, + FX_DWORD size) { + if (!hFont) { + return 0; + } + return ((IFPF_Font*)hFont)->GetFontData(table, buffer, size); } -FX_BOOL CFX_AndroidFontInfo::GetFontCharset(void* hFont, int& charset) -{ - if (!hFont) { - return FALSE; - } - charset = ((IFPF_Font*)hFont)->GetCharset(); +FX_BOOL CFX_AndroidFontInfo::GetFaceName(void* hFont, CFX_ByteString& name) { + if (!hFont) { return FALSE; + } + name = ((IFPF_Font*)hFont)->GetFamilyName(); + return TRUE; } -void CFX_AndroidFontInfo::DeleteFont(void* hFont) -{ - if (!hFont) { - return; - } - ((IFPF_Font*)hFont)->Release(); +FX_BOOL CFX_AndroidFontInfo::GetFontCharset(void* hFont, int& charset) { + if (!hFont) { + return FALSE; + } + charset = ((IFPF_Font*)hFont)->GetCharset(); + return FALSE; } -void* CFX_AndroidFontInfo::RetainFont(void* hFont) -{ - return NULL; +void CFX_AndroidFontInfo::DeleteFont(void* hFont) { + if (!hFont) { + return; + } + ((IFPF_Font*)hFont)->Release(); +} +void* CFX_AndroidFontInfo::RetainFont(void* hFont) { + return NULL; } #endif diff --git a/core/src/fxge/android/fx_android_font.h b/core/src/fxge/android/fx_android_font.h index e0101b380b..5675e1cdc2 100644 --- a/core/src/fxge/android/fx_android_font.h +++ b/core/src/fxge/android/fx_android_font.h @@ -9,29 +9,34 @@ #if _FX_OS_ == _FX_ANDROID_ class IFPF_FontMgr; -class CFX_AndroidFontInfo : public IFX_SystemFontInfo -{ -public: - CFX_AndroidFontInfo(); - virtual void Release() - { - delete this; - } - - virtual FX_BOOL EnumFontList(CFX_FontMapper* pMapper); - - virtual void* MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, const FX_CHAR* face, int& bExact); - - virtual void* GetFont(const FX_CHAR* face); - virtual FX_DWORD GetFontData(void* hFont, FX_DWORD table, uint8_t* buffer, FX_DWORD size); - virtual FX_BOOL GetFaceName(void* hFont, CFX_ByteString& name); - virtual FX_BOOL GetFontCharset(void* hFont, int& charset); - - virtual void DeleteFont(void* hFont); - virtual void* RetainFont(void* hFont); - FX_BOOL Init(IFPF_FontMgr *pFontMgr); -protected: - IFPF_FontMgr *m_pFontMgr; +class CFX_AndroidFontInfo : public IFX_SystemFontInfo { + public: + CFX_AndroidFontInfo(); + virtual void Release() { delete this; } + + virtual FX_BOOL EnumFontList(CFX_FontMapper* pMapper); + + virtual void* MapFont(int weight, + FX_BOOL bItalic, + int charset, + int pitch_family, + const FX_CHAR* face, + int& bExact); + + virtual void* GetFont(const FX_CHAR* face); + virtual FX_DWORD GetFontData(void* hFont, + FX_DWORD table, + uint8_t* buffer, + FX_DWORD size); + virtual FX_BOOL GetFaceName(void* hFont, CFX_ByteString& name); + virtual FX_BOOL GetFontCharset(void* hFont, int& charset); + + virtual void DeleteFont(void* hFont); + virtual void* RetainFont(void* hFont); + FX_BOOL Init(IFPF_FontMgr* pFontMgr); + + protected: + IFPF_FontMgr* m_pFontMgr; }; #endif diff --git a/core/src/fxge/android/fx_android_imp.cpp b/core/src/fxge/android/fx_android_imp.cpp index 7e698cb068..073a665560 100644 --- a/core/src/fxge/android/fx_android_imp.cpp +++ b/core/src/fxge/android/fx_android_imp.cpp @@ -6,24 +6,22 @@ #include "fx_fpf.h" #if _FX_OS_ == _FX_ANDROID_ -void CFX_GEModule::InitPlatform() -{ - IFPF_DeviceModule *pDeviceModule = FPF_GetDeviceModule(); - if (!pDeviceModule) { - return; - } - IFPF_FontMgr *pFontMgr = pDeviceModule->GetFontMgr(); - if (pFontMgr) { - CFX_AndroidFontInfo *pFontInfo = new CFX_AndroidFontInfo; - pFontInfo->Init(pFontMgr); - m_pFontMgr->SetSystemFontInfo(pFontInfo); - } - m_pPlatformData = pDeviceModule; +void CFX_GEModule::InitPlatform() { + IFPF_DeviceModule* pDeviceModule = FPF_GetDeviceModule(); + if (!pDeviceModule) { + return; + } + IFPF_FontMgr* pFontMgr = pDeviceModule->GetFontMgr(); + if (pFontMgr) { + CFX_AndroidFontInfo* pFontInfo = new CFX_AndroidFontInfo; + pFontInfo->Init(pFontMgr); + m_pFontMgr->SetSystemFontInfo(pFontInfo); + } + m_pPlatformData = pDeviceModule; } -void CFX_GEModule::DestroyPlatform() -{ - if (m_pPlatformData) { - ((IFPF_DeviceModule*)m_pPlatformData)->Destroy(); - } +void CFX_GEModule::DestroyPlatform() { + if (m_pPlatformData) { + ((IFPF_DeviceModule*)m_pPlatformData)->Destroy(); + } } #endif diff --git a/core/src/fxge/apple/apple_int.h b/core/src/fxge/apple/apple_int.h index 090ac0924a..ba3d0a83e8 100644 --- a/core/src/fxge/apple/apple_int.h +++ b/core/src/fxge/apple/apple_int.h @@ -7,234 +7,257 @@ #ifndef CORE_SRC_FXGE_APPLE_APPLE_INT_H_ #define CORE_SRC_FXGE_APPLE_APPLE_INT_H_ -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ #if _FX_OS_ == _FX_MACOSX_ #include #endif typedef enum eFXIOSFONTCHARSET { - eFXFontCharsetDEFAULT = 0, - eFXFontCharsetANSI = 1, - eFXFontCharsetSYMBOL = 1 << 1, - eFXFontCharsetSHIFTJIS = 1 << 2, - eFXFontCharsetHANGEUL = 1 << 3, - eFXFontCharsetGB2312 = 1 << 4, - eFXFontCharsetCHINESEBIG5 = 1 << 5, - eFXFontCharsetTHAI = 1 << 6, - eFXFontCharsetEASTEUROPE = 1 << 7, - eFXFontCharsetRUSSIAN = 1 << 8, - eFXFontCharsetGREEK = 1 << 9, - eFXFontCharsetTURKISH = 1 << 10, - eFXFontCharsetHEBREW = 1 << 11, - eFXFontCharsetARABIC = 1 << 12, - eFXFontCharsetBALTIC = 1 << 13, + eFXFontCharsetDEFAULT = 0, + eFXFontCharsetANSI = 1, + eFXFontCharsetSYMBOL = 1 << 1, + eFXFontCharsetSHIFTJIS = 1 << 2, + eFXFontCharsetHANGEUL = 1 << 3, + eFXFontCharsetGB2312 = 1 << 4, + eFXFontCharsetCHINESEBIG5 = 1 << 5, + eFXFontCharsetTHAI = 1 << 6, + eFXFontCharsetEASTEUROPE = 1 << 7, + eFXFontCharsetRUSSIAN = 1 << 8, + eFXFontCharsetGREEK = 1 << 9, + eFXFontCharsetTURKISH = 1 << 10, + eFXFontCharsetHEBREW = 1 << 11, + eFXFontCharsetARABIC = 1 << 12, + eFXFontCharsetBALTIC = 1 << 13, } FX_IOSCHARSET; FX_IOSCHARSET FX_GetiOSCharset(int charset); typedef enum eFXIOSFONTFLAG { - eFXFontFlagBold = 1, - eFXFontFlagItalic = 1 << 1, - eFXFontFlagFixedPitch = 1 << 2, - eFXFontFlagSerif = 1 << 3, - eFXFontFlagScript = 1 << 4, + eFXFontFlagBold = 1, + eFXFontFlagItalic = 1 << 1, + eFXFontFlagFixedPitch = 1 << 2, + eFXFontFlagSerif = 1 << 3, + eFXFontFlagScript = 1 << 4, } FX_IOSFONTFLAG; typedef struct _IOS_FONTDATA { - FX_DWORD nHashCode; - const char* psName; - FX_DWORD charsets; - FX_DWORD styles; + FX_DWORD nHashCode; + const char* psName; + FX_DWORD charsets; + FX_DWORD styles; } IOS_FONTDATA; -class CQuartz2D -{ -public: - void* createGraphics(CFX_DIBitmap* bitmap); - void destroyGraphics(void* graphics); +class CQuartz2D { + public: + void* createGraphics(CFX_DIBitmap* bitmap); + void destroyGraphics(void* graphics); - void* CreateFont(const uint8_t* pFontData, FX_DWORD dwFontSize); - void DestroyFont(void* pFont); - void setGraphicsTextMatrix(void* graphics, CFX_AffineMatrix* matrix); - FX_BOOL drawGraphicsString(void* graphics, - void* font, - FX_FLOAT fontSize, - FX_WORD* glyphIndices, - CGPoint* glyphPositions, - int32_t chars, - FX_ARGB argb, - CFX_AffineMatrix* matrix = NULL); - void saveGraphicsState(void* graphics); - void restoreGraphicsState(void* graphics); + void* CreateFont(const uint8_t* pFontData, FX_DWORD dwFontSize); + void DestroyFont(void* pFont); + void setGraphicsTextMatrix(void* graphics, CFX_AffineMatrix* matrix); + FX_BOOL drawGraphicsString(void* graphics, + void* font, + FX_FLOAT fontSize, + FX_WORD* glyphIndices, + CGPoint* glyphPositions, + int32_t chars, + FX_ARGB argb, + CFX_AffineMatrix* matrix = NULL); + void saveGraphicsState(void* graphics); + void restoreGraphicsState(void* graphics); }; -class CApplePlatform -{ -public: - CApplePlatform() {} - ~CApplePlatform() {} +class CApplePlatform { + public: + CApplePlatform() {} + ~CApplePlatform() {} - CQuartz2D _quartz2d; + CQuartz2D _quartz2d; }; -class CFX_QuartzDeviceDriver : public IFX_RenderDeviceDriver -{ -public: - CFX_QuartzDeviceDriver(CGContextRef context, int32_t deviceClass); - virtual ~CFX_QuartzDeviceDriver(); +class CFX_QuartzDeviceDriver : public IFX_RenderDeviceDriver { + public: + CFX_QuartzDeviceDriver(CGContextRef context, int32_t deviceClass); + virtual ~CFX_QuartzDeviceDriver(); - virtual int GetDeviceCaps(int caps_id); - virtual CFX_Matrix GetCTM() const; - virtual CFX_DIBitmap* GetBackDrop() - { - return NULL; - } - virtual void* GetPlatformSurface() - { - return NULL; - } - virtual FX_BOOL IsPSPrintDriver() - { - return FALSE; - } - virtual FX_BOOL StartRendering() - { - return TRUE; - } - virtual void EndRendering() {} - virtual void SaveState(); - virtual void RestoreState(FX_BOOL bKeepSaved); - virtual FX_BOOL SetClip_PathFill(const CFX_PathData* pPathData, + virtual int GetDeviceCaps(int caps_id); + virtual CFX_Matrix GetCTM() const; + virtual CFX_DIBitmap* GetBackDrop() { return NULL; } + virtual void* GetPlatformSurface() { return NULL; } + virtual FX_BOOL IsPSPrintDriver() { return FALSE; } + virtual FX_BOOL StartRendering() { return TRUE; } + virtual void EndRendering() {} + virtual void SaveState(); + virtual void RestoreState(FX_BOOL bKeepSaved); + virtual FX_BOOL SetClip_PathFill(const CFX_PathData* pPathData, + const CFX_AffineMatrix* pObject2Device, + int fill_mode); + virtual FX_BOOL SetClip_PathStroke(const CFX_PathData* pPathData, const CFX_AffineMatrix* pObject2Device, - int fill_mode - ); - virtual FX_BOOL SetClip_PathStroke(const CFX_PathData* pPathData, - const CFX_AffineMatrix* pObject2Device, - const CFX_GraphStateData* pGraphState - ); - virtual FX_BOOL DrawPath(const CFX_PathData* pPathData, - const CFX_AffineMatrix* pObject2Device, - const CFX_GraphStateData* pGraphState, - FX_DWORD fill_color, - FX_DWORD stroke_color, - int fill_mode, - int alpha_flag = 0, - void* pIccTransform = NULL, - int blend_type = FXDIB_BLEND_NORMAL - ); - virtual FX_BOOL SetPixel(int x, int y, FX_DWORD color, - int alpha_flag = 0, void* pIccTransform = NULL) - { - return FALSE; - } - virtual FX_BOOL FillRect(const FX_RECT* pRect, FX_DWORD fill_color, - int alpha_flag = 0, void* pIccTransform = NULL, int blend_type = FXDIB_BLEND_NORMAL); - virtual FX_BOOL DrawCosmeticLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2, FX_DWORD color, - int alpha_flag = 0, void* pIccTransform = NULL, int blend_type = FXDIB_BLEND_NORMAL); - virtual FX_BOOL GetClipBox(FX_RECT* pRect); - virtual FX_BOOL GetDIBits(CFX_DIBitmap* pBitmap, int left, int top, void* pIccTransform = NULL, FX_BOOL bDEdge = FALSE); - virtual FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, const FX_RECT* pSrcRect, - int dest_left, int dest_top, int blend_type, - int alpha_flag = 0, void* pIccTransform = NULL); - virtual FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, int dest_left, int dest_top, - int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags, - int alpha_flag = 0, void* pIccTransform = NULL, int blend_type = FXDIB_BLEND_NORMAL); - virtual FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap, int bitmap_alpha, FX_DWORD color, - const CFX_AffineMatrix* pMatrix, FX_DWORD flags, void*& handle, - int alpha_flag = 0, void* pIccTransform = NULL, - int blend_type = FXDIB_BLEND_NORMAL) - { - return FALSE; - } - virtual FX_BOOL ContinueDIBits(void* handle, IFX_Pause* pPause) - { - return FALSE; - } - virtual void CancelDIBits(void* handle) {} - virtual FX_BOOL DrawDeviceText(int nChars, const FXTEXT_CHARPOS* pCharPos, CFX_Font* pFont, - CFX_FontCache* pCache, const CFX_AffineMatrix* pObject2Device, FX_FLOAT font_size, FX_DWORD color, - int alpha_flag = 0, void* pIccTransform = NULL); - virtual void ClearDriver(); -protected: - void setStrokeInfo(const CFX_GraphStateData * graphState, FX_ARGB argb, FX_FLOAT lineWidth); - void setFillInfo(FX_ARGB argb); - void setPathToContext(const CFX_PathData * pathData); - FX_FLOAT getLineWidth(const CFX_GraphStateData * graphState, CGAffineTransform ctm); - FX_BOOL CG_DrawGlypRun(int nChars, - const FXTEXT_CHARPOS* pCharPos, - CFX_Font* pFont, - CFX_FontCache* pCache, - const CFX_AffineMatrix* pGlyphMatrix, - const CFX_AffineMatrix* pObject2Device, - FX_FLOAT font_size, - FX_DWORD argb, - int alpha_flag, - void* pIccTransform); - void CG_SetImageTransform(int dest_left, int dest_top, int dest_width, int dest_height, CGRect* rect = NULL); -protected: - CGContextRef _context; - CGAffineTransform _foxitDevice2User; - CGAffineTransform _user2FoxitDevice; - int32_t m_saveCount; + const CFX_GraphStateData* pGraphState); + virtual FX_BOOL DrawPath(const CFX_PathData* pPathData, + const CFX_AffineMatrix* pObject2Device, + const CFX_GraphStateData* pGraphState, + FX_DWORD fill_color, + FX_DWORD stroke_color, + int fill_mode, + int alpha_flag = 0, + void* pIccTransform = NULL, + int blend_type = FXDIB_BLEND_NORMAL); + virtual FX_BOOL SetPixel(int x, + int y, + FX_DWORD color, + int alpha_flag = 0, + void* pIccTransform = NULL) { + return FALSE; + } + virtual FX_BOOL FillRect(const FX_RECT* pRect, + FX_DWORD fill_color, + int alpha_flag = 0, + void* pIccTransform = NULL, + int blend_type = FXDIB_BLEND_NORMAL); + virtual FX_BOOL DrawCosmeticLine(FX_FLOAT x1, + FX_FLOAT y1, + FX_FLOAT x2, + FX_FLOAT y2, + FX_DWORD color, + int alpha_flag = 0, + void* pIccTransform = NULL, + int blend_type = FXDIB_BLEND_NORMAL); + virtual FX_BOOL GetClipBox(FX_RECT* pRect); + virtual FX_BOOL GetDIBits(CFX_DIBitmap* pBitmap, + int left, + int top, + void* pIccTransform = NULL, + FX_BOOL bDEdge = FALSE); + virtual FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap, + FX_DWORD color, + const FX_RECT* pSrcRect, + int dest_left, + int dest_top, + int blend_type, + int alpha_flag = 0, + void* pIccTransform = NULL); + virtual FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap, + FX_DWORD color, + int dest_left, + int dest_top, + int dest_width, + int dest_height, + const FX_RECT* pClipRect, + FX_DWORD flags, + int alpha_flag = 0, + void* pIccTransform = NULL, + int blend_type = FXDIB_BLEND_NORMAL); + virtual FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap, + int bitmap_alpha, + FX_DWORD color, + const CFX_AffineMatrix* pMatrix, + FX_DWORD flags, + void*& handle, + int alpha_flag = 0, + void* pIccTransform = NULL, + int blend_type = FXDIB_BLEND_NORMAL) { + return FALSE; + } + virtual FX_BOOL ContinueDIBits(void* handle, IFX_Pause* pPause) { + return FALSE; + } + virtual void CancelDIBits(void* handle) {} + virtual FX_BOOL DrawDeviceText(int nChars, + const FXTEXT_CHARPOS* pCharPos, + CFX_Font* pFont, + CFX_FontCache* pCache, + const CFX_AffineMatrix* pObject2Device, + FX_FLOAT font_size, + FX_DWORD color, + int alpha_flag = 0, + void* pIccTransform = NULL); + virtual void ClearDriver(); - int32_t _width; - int32_t _height; - int32_t _bitsPerPixel; - int32_t _deviceClass; - int32_t _renderCaps; - int32_t _horzSize; - int32_t _vertSize; + protected: + void setStrokeInfo(const CFX_GraphStateData* graphState, + FX_ARGB argb, + FX_FLOAT lineWidth); + void setFillInfo(FX_ARGB argb); + void setPathToContext(const CFX_PathData* pathData); + FX_FLOAT getLineWidth(const CFX_GraphStateData* graphState, + CGAffineTransform ctm); + FX_BOOL CG_DrawGlypRun(int nChars, + const FXTEXT_CHARPOS* pCharPos, + CFX_Font* pFont, + CFX_FontCache* pCache, + const CFX_AffineMatrix* pGlyphMatrix, + const CFX_AffineMatrix* pObject2Device, + FX_FLOAT font_size, + FX_DWORD argb, + int alpha_flag, + void* pIccTransform); + void CG_SetImageTransform(int dest_left, + int dest_top, + int dest_width, + int dest_height, + CGRect* rect = NULL); + + protected: + CGContextRef _context; + CGAffineTransform _foxitDevice2User; + CGAffineTransform _user2FoxitDevice; + int32_t m_saveCount; + + int32_t _width; + int32_t _height; + int32_t _bitsPerPixel; + int32_t _deviceClass; + int32_t _renderCaps; + int32_t _horzSize; + int32_t _vertSize; }; -class CFX_FontProvider final : public IFX_FileRead -{ -public: - virtual void Release() override - { - delete this; - } - virtual FX_FILESIZE GetSize() override - { - return (FX_FILESIZE)_totalSize; - } - virtual FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override; +class CFX_FontProvider final : public IFX_FileRead { + public: + virtual void Release() override { delete this; } + virtual FX_FILESIZE GetSize() override { return (FX_FILESIZE)_totalSize; } + virtual FX_BOOL ReadBlock(void* buffer, + FX_FILESIZE offset, + size_t size) override; + + virtual FX_BOOL IsEOF() override { return _offSet == _totalSize; } + virtual FX_FILESIZE GetPosition() override { return (FX_FILESIZE)_offSet; } + virtual size_t ReadBlock(void* buffer, size_t size) override; + + public: + CFX_FontProvider(CGFontRef cgFont); + ~CFX_FontProvider(); + void InitTableOffset(); + unsigned long Read(unsigned long offset, + unsigned char* buffer, + unsigned long count); + + protected: + uint32_t CalcTableCheckSum(const uint32_t* table, + uint32_t numberOfBytesInTable); + uint32_t CalcTableDataRefCheckSum(CFDataRef dataRef); - virtual FX_BOOL IsEOF() override - { - return _offSet == _totalSize; - } - virtual FX_FILESIZE GetPosition() override - { - return (FX_FILESIZE)_offSet; - } - virtual size_t ReadBlock(void* buffer, size_t size) override; -public: - CFX_FontProvider(CGFontRef cgFont); - ~CFX_FontProvider(); - void InitTableOffset(); - unsigned long Read(unsigned long offset, unsigned char *buffer, unsigned long count); -protected: - uint32_t CalcTableCheckSum(const uint32_t *table, uint32_t numberOfBytesInTable); - uint32_t CalcTableDataRefCheckSum(CFDataRef dataRef); -private: - CGFontRef m_cgFont; - UInt32 m_iTableSize; - size_t _offSet; - typedef struct FontHeader { - int32_t fVersion; - uint16_t fNumTables; - uint16_t fSearchRange; - uint16_t fEntrySelector; - uint16_t fRangeShift; - } FontHeader; - typedef struct TableEntry { - uint32_t fTag; - uint32_t fCheckSum; - uint32_t fOffset; - uint32_t fLength; - } TableEntry; - FontHeader _fontHeader; - unsigned char * _tableEntries; - size_t * _tableOffsets; - int _tableCount; - int _totalSize; + private: + CGFontRef m_cgFont; + UInt32 m_iTableSize; + size_t _offSet; + typedef struct FontHeader { + int32_t fVersion; + uint16_t fNumTables; + uint16_t fSearchRange; + uint16_t fEntrySelector; + uint16_t fRangeShift; + } FontHeader; + typedef struct TableEntry { + uint32_t fTag; + uint32_t fCheckSum; + uint32_t fOffset; + uint32_t fLength; + } TableEntry; + FontHeader _fontHeader; + unsigned char* _tableEntries; + size_t* _tableOffsets; + int _tableCount; + int _totalSize; }; -uint32_t FX_GetHashCode( const FX_CHAR* pStr); -FX_DWORD FX_IOSGetMatchFamilyNameHashcode(const FX_CHAR* pFontName); +uint32_t FX_GetHashCode(const FX_CHAR* pStr); +FX_DWORD FX_IOSGetMatchFamilyNameHashcode(const FX_CHAR* pFontName); uint32_t FX_IOSGetFamilyNamesCount(); -const FX_CHAR* FX_IOSGetFamilyName( uint32_t uIndex); +const FX_CHAR* FX_IOSGetFamilyName(uint32_t uIndex); #endif #endif // CORE_SRC_FXGE_APPLE_APPLE_INT_H_ diff --git a/core/src/fxge/apple/fx_apple_platform.cpp b/core/src/fxge/apple/fx_apple_platform.cpp index 9db807c3af..95cd1a1dd8 100644 --- a/core/src/fxge/apple/fx_apple_platform.cpp +++ b/core/src/fxge/apple/fx_apple_platform.cpp @@ -7,7 +7,7 @@ #include "../../../include/fxcrt/fx_system.h" #include "../../../include/fxge/fx_ge.h" -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ #include "../../../include/fxge/fx_freetype.h" #include "../../../include/fxge/fx_ge_apple.h" @@ -16,159 +16,159 @@ #include "../ge/text_int.h" #include "apple_int.h" -void CFX_AggDeviceDriver::InitPlatform() -{ - CQuartz2D & quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d; - m_pPlatformGraphics = quartz2d.createGraphics(m_pBitmap); +void CFX_AggDeviceDriver::InitPlatform() { + CQuartz2D& quartz2d = + ((CApplePlatform*)CFX_GEModule::Get()->GetPlatformData())->_quartz2d; + m_pPlatformGraphics = quartz2d.createGraphics(m_pBitmap); } -void CFX_AggDeviceDriver::DestroyPlatform() -{ - CQuartz2D & quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d; - if (m_pPlatformGraphics) { - quartz2d.destroyGraphics(m_pPlatformGraphics); - m_pPlatformGraphics = NULL; - } +void CFX_AggDeviceDriver::DestroyPlatform() { + CQuartz2D& quartz2d = + ((CApplePlatform*)CFX_GEModule::Get()->GetPlatformData())->_quartz2d; + if (m_pPlatformGraphics) { + quartz2d.destroyGraphics(m_pPlatformGraphics); + m_pPlatformGraphics = NULL; + } } void CFX_FaceCache::InitPlatform() {} void CFX_FaceCache::DestroyPlatform() {} -CFX_GlyphBitmap* CFX_FaceCache::RenderGlyph_Nativetext(CFX_Font * pFont, - FX_DWORD glyph_index, - const CFX_AffineMatrix * pMatrix, - int dest_width, - int anti_alias) -{ - return NULL; +CFX_GlyphBitmap* CFX_FaceCache::RenderGlyph_Nativetext( + CFX_Font* pFont, + FX_DWORD glyph_index, + const CFX_AffineMatrix* pMatrix, + int dest_width, + int anti_alias) { + return NULL; } -static FX_BOOL _CGDrawGlyphRun(CGContextRef pContext, - int nChars, - const FXTEXT_CHARPOS* pCharPos, - CFX_Font* pFont, - CFX_FontCache* pCache, - const CFX_AffineMatrix* pObject2Device, - FX_FLOAT font_size, - FX_DWORD argb, - int alpha_flag, - void* pIccTransform) -{ - if (nChars == 0) { - return TRUE; - } - CFX_AffineMatrix new_matrix; - FX_BOOL bNegSize = font_size < 0; - if (bNegSize) { - font_size = -font_size; - } - FX_FLOAT ori_x = pCharPos[0].m_OriginX, ori_y = pCharPos[0].m_OriginY; - new_matrix.Transform(ori_x, ori_y); - if (pObject2Device) { - new_matrix.Concat(*pObject2Device); +static FX_BOOL _CGDrawGlyphRun(CGContextRef pContext, + int nChars, + const FXTEXT_CHARPOS* pCharPos, + CFX_Font* pFont, + CFX_FontCache* pCache, + const CFX_AffineMatrix* pObject2Device, + FX_FLOAT font_size, + FX_DWORD argb, + int alpha_flag, + void* pIccTransform) { + if (nChars == 0) { + return TRUE; + } + CFX_AffineMatrix new_matrix; + FX_BOOL bNegSize = font_size < 0; + if (bNegSize) { + font_size = -font_size; + } + FX_FLOAT ori_x = pCharPos[0].m_OriginX, ori_y = pCharPos[0].m_OriginY; + new_matrix.Transform(ori_x, ori_y); + if (pObject2Device) { + new_matrix.Concat(*pObject2Device); + } + CQuartz2D& quartz2d = + ((CApplePlatform*)CFX_GEModule::Get()->GetPlatformData())->_quartz2d; + if (!pFont->m_pPlatformFont) { + if (pFont->GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) { + return FALSE; } - CQuartz2D& quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d; - if (!pFont->m_pPlatformFont) { - if (pFont->GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) { - return FALSE; - } - pFont->m_pPlatformFont = quartz2d.CreateFont(pFont->m_pFontData, pFont->m_dwSize); - if (NULL == pFont->m_pPlatformFont) { - return FALSE; - } - } - CFX_FixedBufGrow glyph_indices(nChars); - CFX_FixedBufGrow glyph_positions(nChars); - for (int i = 0; i < nChars; i++ ) { - glyph_indices[i] = pCharPos[i].m_ExtGID; - if (bNegSize) { - glyph_positions[i].x = -pCharPos[i].m_OriginX; - } else { - glyph_positions[i].x = pCharPos[i].m_OriginX; - } - glyph_positions[i].y = pCharPos[i].m_OriginY; + pFont->m_pPlatformFont = + quartz2d.CreateFont(pFont->m_pFontData, pFont->m_dwSize); + if (NULL == pFont->m_pPlatformFont) { + return FALSE; } + } + CFX_FixedBufGrow glyph_indices(nChars); + CFX_FixedBufGrow glyph_positions(nChars); + for (int i = 0; i < nChars; i++) { + glyph_indices[i] = pCharPos[i].m_ExtGID; if (bNegSize) { - new_matrix.a = -new_matrix.a; + glyph_positions[i].x = -pCharPos[i].m_OriginX; } else { - new_matrix.b = -new_matrix.b; - new_matrix.d = -new_matrix.d; + glyph_positions[i].x = pCharPos[i].m_OriginX; } - quartz2d.setGraphicsTextMatrix(pContext, &new_matrix); - return quartz2d.drawGraphicsString(pContext, - pFont->m_pPlatformFont, - font_size, - glyph_indices, - glyph_positions, - nChars, - argb, - NULL); + glyph_positions[i].y = pCharPos[i].m_OriginY; + } + if (bNegSize) { + new_matrix.a = -new_matrix.a; + } else { + new_matrix.b = -new_matrix.b; + new_matrix.d = -new_matrix.d; + } + quartz2d.setGraphicsTextMatrix(pContext, &new_matrix); + return quartz2d.drawGraphicsString(pContext, pFont->m_pPlatformFont, + font_size, glyph_indices, glyph_positions, + nChars, argb, NULL); } -static void _DoNothing(void *info, const void *data, size_t size) {} -FX_BOOL CFX_AggDeviceDriver::DrawDeviceText(int nChars, - const FXTEXT_CHARPOS * pCharPos, - CFX_Font * pFont, - CFX_FontCache * pCache, - const CFX_AffineMatrix * pObject2Device, - FX_FLOAT font_size, - FX_DWORD argb, - int alpha_flag, void* pIccTransform) -{ - if (!pFont) { - return FALSE; - } - FX_BOOL bBold = pFont->IsBold(); - if (!bBold && pFont->GetSubstFont() && - pFont->GetSubstFont()->m_Weight >= 500 && - pFont->GetSubstFont()->m_Weight <= 600) { - return FALSE; - } - for (int i = 0; i < nChars; i ++) { - if (pCharPos[i].m_bGlyphAdjust) { - return FALSE; - } +static void _DoNothing(void* info, const void* data, size_t size) {} +FX_BOOL CFX_AggDeviceDriver::DrawDeviceText( + int nChars, + const FXTEXT_CHARPOS* pCharPos, + CFX_Font* pFont, + CFX_FontCache* pCache, + const CFX_AffineMatrix* pObject2Device, + FX_FLOAT font_size, + FX_DWORD argb, + int alpha_flag, + void* pIccTransform) { + if (!pFont) { + return FALSE; + } + FX_BOOL bBold = pFont->IsBold(); + if (!bBold && pFont->GetSubstFont() && + pFont->GetSubstFont()->m_Weight >= 500 && + pFont->GetSubstFont()->m_Weight <= 600) { + return FALSE; + } + for (int i = 0; i < nChars; i++) { + if (pCharPos[i].m_bGlyphAdjust) { + return FALSE; } - CGContextRef ctx = CGContextRef(m_pPlatformGraphics); - if (NULL == ctx) { - return FALSE; + } + CGContextRef ctx = CGContextRef(m_pPlatformGraphics); + if (NULL == ctx) { + return FALSE; + } + CGContextSaveGState(ctx); + CGContextSetTextDrawingMode(ctx, kCGTextFillClip); + CGRect rect_cg; + CGImageRef pImageCG = NULL; + if (m_pClipRgn) { + rect_cg = + CGRectMake(m_pClipRgn->GetBox().left, m_pClipRgn->GetBox().top, + m_pClipRgn->GetBox().Width(), m_pClipRgn->GetBox().Height()); + const CFX_DIBitmap* pClipMask = m_pClipRgn->GetMask(); + if (pClipMask) { + CGDataProviderRef pClipMaskDataProvider = CGDataProviderCreateWithData( + NULL, pClipMask->GetBuffer(), + pClipMask->GetPitch() * pClipMask->GetHeight(), _DoNothing); + CGFloat decode_f[2] = {255.f, 0.f}; + pImageCG = CGImageMaskCreate( + pClipMask->GetWidth(), pClipMask->GetHeight(), 8, 8, + pClipMask->GetPitch(), pClipMaskDataProvider, decode_f, FALSE); + CGDataProviderRelease(pClipMaskDataProvider); } - CGContextSaveGState(ctx); - CGContextSetTextDrawingMode(ctx, kCGTextFillClip); - CGRect rect_cg; - CGImageRef pImageCG = NULL; - if (m_pClipRgn) { - rect_cg = CGRectMake(m_pClipRgn->GetBox().left, m_pClipRgn->GetBox().top, m_pClipRgn->GetBox().Width(), m_pClipRgn->GetBox().Height()); - const CFX_DIBitmap* pClipMask = m_pClipRgn->GetMask(); - if (pClipMask) { - CGDataProviderRef pClipMaskDataProvider = CGDataProviderCreateWithData(NULL, - pClipMask->GetBuffer(), - pClipMask->GetPitch() * pClipMask->GetHeight(), - _DoNothing); - CGFloat decode_f[2] = {255.f, 0.f}; - pImageCG = CGImageMaskCreate(pClipMask->GetWidth(), pClipMask->GetHeight(), - 8, 8, pClipMask->GetPitch(), pClipMaskDataProvider, - decode_f, FALSE); - CGDataProviderRelease(pClipMaskDataProvider); - } - } else { - rect_cg = CGRectMake(0, 0, m_pBitmap->GetWidth(), m_pBitmap->GetHeight()); - } - rect_cg = CGContextConvertRectToDeviceSpace(ctx, rect_cg); - if (pImageCG) { - CGContextClipToMask(ctx, rect_cg, pImageCG); - } else { - CGContextClipToRect(ctx, rect_cg); - } - FX_BOOL ret = _CGDrawGlyphRun(ctx, nChars, pCharPos, pFont, pCache, pObject2Device, font_size, argb, alpha_flag, pIccTransform); - if (pImageCG) { - CGImageRelease(pImageCG); - } - CGContextRestoreGState(ctx); - return ret; + } else { + rect_cg = CGRectMake(0, 0, m_pBitmap->GetWidth(), m_pBitmap->GetHeight()); + } + rect_cg = CGContextConvertRectToDeviceSpace(ctx, rect_cg); + if (pImageCG) { + CGContextClipToMask(ctx, rect_cg, pImageCG); + } else { + CGContextClipToRect(ctx, rect_cg); + } + FX_BOOL ret = + _CGDrawGlyphRun(ctx, nChars, pCharPos, pFont, pCache, pObject2Device, + font_size, argb, alpha_flag, pIccTransform); + if (pImageCG) { + CGImageRelease(pImageCG); + } + CGContextRestoreGState(ctx); + return ret; } -void CFX_Font::ReleasePlatformResource() -{ - if (m_pPlatformFont) { - CQuartz2D & quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d; - quartz2d.DestroyFont(m_pPlatformFont); - m_pPlatformFont = NULL; - } +void CFX_Font::ReleasePlatformResource() { + if (m_pPlatformFont) { + CQuartz2D& quartz2d = + ((CApplePlatform*)CFX_GEModule::Get()->GetPlatformData())->_quartz2d; + quartz2d.DestroyFont(m_pPlatformFont); + m_pPlatformFont = NULL; + } } #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ diff --git a/core/src/fxge/apple/fx_mac_imp.cpp b/core/src/fxge/apple/fx_mac_imp.cpp index 1bcbc9d194..9918ba97e8 100644 --- a/core/src/fxge/apple/fx_mac_imp.cpp +++ b/core/src/fxge/apple/fx_mac_imp.cpp @@ -8,10 +8,9 @@ #include "apple_int.h" #if _FX_OS_ == _FX_MACOSX_ static const struct { - const FX_CHAR* m_pName; - const FX_CHAR* m_pSubstName; -} -Base14Substs[] = { + const FX_CHAR* m_pName; + const FX_CHAR* m_pSubstName; +} Base14Substs[] = { {"Courier", "Courier New"}, {"Courier-Bold", "Courier New Bold"}, {"Courier-BoldOblique", "Courier New Bold Italic"}, @@ -25,82 +24,88 @@ Base14Substs[] = { {"Times-BoldItalic", "Times New Roman Bold Italic"}, {"Times-Italic", "Times New Roman Italic"}, }; -class CFX_MacFontInfo : public CFX_FolderFontInfo -{ -public: - virtual void* MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, const FX_CHAR* family, int& iExact); +class CFX_MacFontInfo : public CFX_FolderFontInfo { + public: + virtual void* MapFont(int weight, + FX_BOOL bItalic, + int charset, + int pitch_family, + const FX_CHAR* family, + int& iExact); }; #define JAPAN_GOTHIC "Hiragino Kaku Gothic Pro W6" #define JAPAN_MINCHO "Hiragino Mincho Pro W6" -static void GetJapanesePreference(CFX_ByteString& face, int weight, int picth_family) -{ - if (face.Find("Gothic") >= 0) { - face = JAPAN_GOTHIC; - return; - } - if (!(picth_family & FXFONT_FF_ROMAN) && weight > 400) { - face = JAPAN_GOTHIC; - } else { - face = JAPAN_MINCHO; - } +static void GetJapanesePreference(CFX_ByteString& face, + int weight, + int picth_family) { + if (face.Find("Gothic") >= 0) { + face = JAPAN_GOTHIC; + return; + } + if (!(picth_family & FXFONT_FF_ROMAN) && weight > 400) { + face = JAPAN_GOTHIC; + } else { + face = JAPAN_MINCHO; + } } -void* CFX_MacFontInfo::MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, const FX_CHAR* cstr_face, int& iExact) -{ - CFX_ByteString face = cstr_face; - int iBaseFont; - for (iBaseFont = 0; iBaseFont < 12; iBaseFont ++) - if (face == CFX_ByteStringC(Base14Substs[iBaseFont].m_pName)) { - face = Base14Substs[iBaseFont].m_pSubstName; - iExact = TRUE; - break; - } - if (iBaseFont < 12) { - return GetFont(face); - } - void* p; - if (m_FontList.Lookup(face, p)) { - return p; - } - if (charset == FXFONT_ANSI_CHARSET && (pitch_family & FXFONT_FF_FIXEDPITCH)) { - return GetFont("Courier New"); - } - if (charset == FXFONT_ANSI_CHARSET || charset == FXFONT_SYMBOL_CHARSET) { - return NULL; - } - switch (charset) { - case FXFONT_SHIFTJIS_CHARSET: - GetJapanesePreference(face, weight, pitch_family); - break; - case FXFONT_GB2312_CHARSET: - face = "STSong"; - break; - case FXFONT_HANGEUL_CHARSET: - face = "AppleMyungjo"; - break; - case FXFONT_CHINESEBIG5_CHARSET: - face = "LiSong Pro Light"; - } - if (m_FontList.Lookup(face, p)) { - return p; +void* CFX_MacFontInfo::MapFont(int weight, + FX_BOOL bItalic, + int charset, + int pitch_family, + const FX_CHAR* cstr_face, + int& iExact) { + CFX_ByteString face = cstr_face; + int iBaseFont; + for (iBaseFont = 0; iBaseFont < 12; iBaseFont++) + if (face == CFX_ByteStringC(Base14Substs[iBaseFont].m_pName)) { + face = Base14Substs[iBaseFont].m_pSubstName; + iExact = TRUE; + break; } + if (iBaseFont < 12) { + return GetFont(face); + } + void* p; + if (m_FontList.Lookup(face, p)) { + return p; + } + if (charset == FXFONT_ANSI_CHARSET && (pitch_family & FXFONT_FF_FIXEDPITCH)) { + return GetFont("Courier New"); + } + if (charset == FXFONT_ANSI_CHARSET || charset == FXFONT_SYMBOL_CHARSET) { return NULL; + } + switch (charset) { + case FXFONT_SHIFTJIS_CHARSET: + GetJapanesePreference(face, weight, pitch_family); + break; + case FXFONT_GB2312_CHARSET: + face = "STSong"; + break; + case FXFONT_HANGEUL_CHARSET: + face = "AppleMyungjo"; + break; + case FXFONT_CHINESEBIG5_CHARSET: + face = "LiSong Pro Light"; + } + if (m_FontList.Lookup(face, p)) { + return p; + } + return NULL; } -IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault() -{ - CFX_MacFontInfo* pInfo = new CFX_MacFontInfo; - pInfo->AddPath("~/Library/Fonts"); - pInfo->AddPath("/Library/Fonts"); - pInfo->AddPath("/System/Library/Fonts"); - return pInfo; +IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault() { + CFX_MacFontInfo* pInfo = new CFX_MacFontInfo; + pInfo->AddPath("~/Library/Fonts"); + pInfo->AddPath("/Library/Fonts"); + pInfo->AddPath("/System/Library/Fonts"); + return pInfo; } -void CFX_GEModule::InitPlatform() -{ - m_pPlatformData = new CApplePlatform; - m_pFontMgr->SetSystemFontInfo(IFX_SystemFontInfo::CreateDefault()); +void CFX_GEModule::InitPlatform() { + m_pPlatformData = new CApplePlatform; + m_pFontMgr->SetSystemFontInfo(IFX_SystemFontInfo::CreateDefault()); } -void CFX_GEModule::DestroyPlatform() -{ - delete (CApplePlatform *)m_pPlatformData; - m_pPlatformData = NULL; +void CFX_GEModule::DestroyPlatform() { + delete (CApplePlatform*)m_pPlatformData; + m_pPlatformData = NULL; } #endif diff --git a/core/src/fxge/apple/fx_quartz_device.cpp b/core/src/fxge/apple/fx_quartz_device.cpp index d1e4f544ba..34851e0c80 100644 --- a/core/src/fxge/apple/fx_quartz_device.cpp +++ b/core/src/fxge/apple/fx_quartz_device.cpp @@ -11,1118 +11,1046 @@ #include "../dib/dib_int.h" #include "../ge/text_int.h" -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ #include "apple_int.h" #include "../../../include/fxge/fx_ge_apple.h" #ifndef CGFLOAT_IS_DOUBLE #error Expected CGFLOAT_IS_DOUBLE to be defined by CoreGraphics headers #endif -void* CQuartz2D::createGraphics(CFX_DIBitmap* pBitmap) -{ - if (!pBitmap) { - return NULL; - } - CGBitmapInfo bmpInfo = kCGBitmapByteOrder32Little; - switch (pBitmap->GetFormat()) { - case FXDIB_Rgb32: - bmpInfo |= kCGImageAlphaNoneSkipFirst; - break; - case FXDIB_Argb: - default: - return NULL; - } - CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); - CGContextRef context = CGBitmapContextCreate(pBitmap->GetBuffer(), - pBitmap->GetWidth(), - pBitmap->GetHeight(), - 8, - pBitmap->GetPitch(), - colorSpace, - bmpInfo); - CGColorSpaceRelease(colorSpace); - return context; +void* CQuartz2D::createGraphics(CFX_DIBitmap* pBitmap) { + if (!pBitmap) { + return NULL; + } + CGBitmapInfo bmpInfo = kCGBitmapByteOrder32Little; + switch (pBitmap->GetFormat()) { + case FXDIB_Rgb32: + bmpInfo |= kCGImageAlphaNoneSkipFirst; + break; + case FXDIB_Argb: + default: + return NULL; + } + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + CGContextRef context = CGBitmapContextCreate( + pBitmap->GetBuffer(), pBitmap->GetWidth(), pBitmap->GetHeight(), 8, + pBitmap->GetPitch(), colorSpace, bmpInfo); + CGColorSpaceRelease(colorSpace); + return context; } -void CQuartz2D::destroyGraphics(void* graphics) -{ - if (graphics) { - CGContextRelease((CGContextRef) graphics); - } +void CQuartz2D::destroyGraphics(void* graphics) { + if (graphics) { + CGContextRelease((CGContextRef)graphics); + } } -void* CQuartz2D::CreateFont(const uint8_t* pFontData, FX_DWORD dwFontSize) -{ - CGDataProviderRef pDataProvider = CGDataProviderCreateWithData(NULL, pFontData, (size_t)dwFontSize, NULL); - if (NULL == pDataProvider) { - return NULL; - } - CGFontRef pCGFont = CGFontCreateWithDataProvider(pDataProvider); - CGDataProviderRelease(pDataProvider); - return pCGFont; +void* CQuartz2D::CreateFont(const uint8_t* pFontData, FX_DWORD dwFontSize) { + CGDataProviderRef pDataProvider = + CGDataProviderCreateWithData(NULL, pFontData, (size_t)dwFontSize, NULL); + if (NULL == pDataProvider) { + return NULL; + } + CGFontRef pCGFont = CGFontCreateWithDataProvider(pDataProvider); + CGDataProviderRelease(pDataProvider); + return pCGFont; } -void CQuartz2D::DestroyFont(void* pFont) -{ - CGFontRelease((CGFontRef)pFont); +void CQuartz2D::DestroyFont(void* pFont) { + CGFontRelease((CGFontRef)pFont); } -void CQuartz2D::setGraphicsTextMatrix(void* graphics, CFX_AffineMatrix* matrix) -{ - if (!graphics || !matrix) { - return; - } - CGContextRef context = (CGContextRef) graphics; - CGFloat ty = CGBitmapContextGetHeight(context) - matrix->f; - CGContextSetTextMatrix(context, CGAffineTransformMake(matrix->a, - matrix->b, - matrix->c, - matrix->d, - matrix->e, - ty)); +void CQuartz2D::setGraphicsTextMatrix(void* graphics, + CFX_AffineMatrix* matrix) { + if (!graphics || !matrix) { + return; + } + CGContextRef context = (CGContextRef)graphics; + CGFloat ty = CGBitmapContextGetHeight(context) - matrix->f; + CGContextSetTextMatrix( + context, CGAffineTransformMake(matrix->a, matrix->b, matrix->c, matrix->d, + matrix->e, ty)); } -FX_BOOL CQuartz2D::drawGraphicsString(void* graphics, - void* font, - FX_FLOAT fontSize, - FX_WORD* glyphIndices, - CGPoint* glyphPositions, - int32_t charsCount, - FX_ARGB argb, - CFX_AffineMatrix* matrix ) -{ - if (!graphics) { - return FALSE; - } - CGContextRef context = (CGContextRef) graphics; - CGContextSetFont(context, (CGFontRef)font); - CGContextSetFontSize(context, fontSize); - if (matrix) { - CGAffineTransform m = CGContextGetTextMatrix(context); - m = CGAffineTransformConcat(m, - CGAffineTransformMake(matrix->a, - matrix->b, - matrix->c, - matrix->d, - matrix->e, - matrix->f)); - CGContextSetTextMatrix(context, m); - } - int32_t a, r, g, b; - ArgbDecode(argb, a, r, g, b); - CGContextSetRGBFillColor(context, - r / 255.f, - g / 255.f, - b / 255.f, - a / 255.f); - CGContextSaveGState(context); +FX_BOOL CQuartz2D::drawGraphicsString(void* graphics, + void* font, + FX_FLOAT fontSize, + FX_WORD* glyphIndices, + CGPoint* glyphPositions, + int32_t charsCount, + FX_ARGB argb, + CFX_AffineMatrix* matrix) { + if (!graphics) { + return FALSE; + } + CGContextRef context = (CGContextRef)graphics; + CGContextSetFont(context, (CGFontRef)font); + CGContextSetFontSize(context, fontSize); + if (matrix) { + CGAffineTransform m = CGContextGetTextMatrix(context); + m = CGAffineTransformConcat( + m, CGAffineTransformMake(matrix->a, matrix->b, matrix->c, matrix->d, + matrix->e, matrix->f)); + CGContextSetTextMatrix(context, m); + } + int32_t a, r, g, b; + ArgbDecode(argb, a, r, g, b); + CGContextSetRGBFillColor(context, r / 255.f, g / 255.f, b / 255.f, a / 255.f); + CGContextSaveGState(context); #if CGFLOAT_IS_DOUBLE - CGPoint* glyphPositionsCG = new CGPoint[charsCount]; - if (!glyphPositionsCG) { - return FALSE; - } - for (int index = 0; index < charsCount; ++index) { - glyphPositionsCG[index].x = glyphPositions[index].x; - glyphPositionsCG[index].y = glyphPositions[index].y; - } + CGPoint* glyphPositionsCG = new CGPoint[charsCount]; + if (!glyphPositionsCG) { + return FALSE; + } + for (int index = 0; index < charsCount; ++index) { + glyphPositionsCG[index].x = glyphPositions[index].x; + glyphPositionsCG[index].y = glyphPositions[index].y; + } #else - CGPoint* glyphPositionsCG = (CGPoint*)glyphPositions; + CGPoint* glyphPositionsCG = (CGPoint*)glyphPositions; #endif - CGContextShowGlyphsAtPositions(context, - (CGGlyph *) glyphIndices, - glyphPositionsCG, - charsCount); + CGContextShowGlyphsAtPositions(context, (CGGlyph*)glyphIndices, + glyphPositionsCG, charsCount); #if CGFLOAT_IS_DOUBLE - delete[] glyphPositionsCG; + delete[] glyphPositionsCG; #endif - CGContextRestoreGState(context); - return TRUE; + CGContextRestoreGState(context); + return TRUE; } -void CQuartz2D::saveGraphicsState(void * graphics) -{ - if (graphics) { - CGContextSaveGState((CGContextRef) graphics); - } +void CQuartz2D::saveGraphicsState(void* graphics) { + if (graphics) { + CGContextSaveGState((CGContextRef)graphics); + } } -void CQuartz2D::restoreGraphicsState(void * graphics) -{ - if (graphics) { - CGContextRestoreGState((CGContextRef) graphics); - } +void CQuartz2D::restoreGraphicsState(void* graphics) { + if (graphics) { + CGContextRestoreGState((CGContextRef)graphics); + } } -static CGContextRef createContextWithBitmap(CFX_DIBitmap* pBitmap) -{ - if (!pBitmap || pBitmap->IsCmykImage() || pBitmap->GetBPP() < 32) { - return NULL; - } - CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Little; - if (pBitmap->HasAlpha()) { - bitmapInfo |= kCGImageAlphaPremultipliedFirst; - } else { - bitmapInfo |= kCGImageAlphaNoneSkipFirst; - } - CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); - CGContextRef context = CGBitmapContextCreate(pBitmap->GetBuffer(), - pBitmap->GetWidth(), - pBitmap->GetHeight(), - 8, - pBitmap->GetPitch(), - colorSpace, - bitmapInfo); - CGColorSpaceRelease(colorSpace); - return context; +static CGContextRef createContextWithBitmap(CFX_DIBitmap* pBitmap) { + if (!pBitmap || pBitmap->IsCmykImage() || pBitmap->GetBPP() < 32) { + return NULL; + } + CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Little; + if (pBitmap->HasAlpha()) { + bitmapInfo |= kCGImageAlphaPremultipliedFirst; + } else { + bitmapInfo |= kCGImageAlphaNoneSkipFirst; + } + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + CGContextRef context = CGBitmapContextCreate( + pBitmap->GetBuffer(), pBitmap->GetWidth(), pBitmap->GetHeight(), 8, + pBitmap->GetPitch(), colorSpace, bitmapInfo); + CGColorSpaceRelease(colorSpace); + return context; } -CFX_QuartzDeviceDriver::CFX_QuartzDeviceDriver(CGContextRef context, int32_t deviceClass) -{ - m_saveCount = 0; - _context = context; - _deviceClass = deviceClass; - CGContextRetain(_context); - CGRect r = CGContextGetClipBoundingBox(context); - _width = FXSYS_round(r.size.width); - _height = FXSYS_round(r.size.height); - _renderCaps = FXRC_SOFT_CLIP | FXRC_BLEND_MODE | - FXRC_ALPHA_PATH | FXRC_ALPHA_IMAGE | - FXRC_BIT_MASK | FXRC_ALPHA_MASK; - if (_deviceClass != FXDC_DISPLAY) { - } else { - CGImageRef image = CGBitmapContextCreateImage(_context); - if (image) { - _renderCaps |= FXRC_GET_BITS; - _width = CGImageGetWidth(image); - _height = CGImageGetHeight(image); - CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(image); - if (kCGImageAlphaPremultipliedFirst == alphaInfo || - kCGImageAlphaPremultipliedLast == alphaInfo || - kCGImageAlphaOnly == alphaInfo) { - _renderCaps |= FXRC_ALPHA_OUTPUT; - } - } - CGImageRelease(image); - } - CGAffineTransform ctm = CGContextGetCTM(_context); - CGContextSaveGState(_context); - m_saveCount++; - if (ctm.d >= 0) { - CGFloat offset_x, offset_y; - offset_x = ctm.tx; - offset_y = ctm.ty; - CGContextTranslateCTM(_context, -offset_x, -offset_y); - CGContextConcatCTM(_context, CGAffineTransformMake(1, 0, 0, -1, offset_x, _height + offset_y)); +CFX_QuartzDeviceDriver::CFX_QuartzDeviceDriver(CGContextRef context, + int32_t deviceClass) { + m_saveCount = 0; + _context = context; + _deviceClass = deviceClass; + CGContextRetain(_context); + CGRect r = CGContextGetClipBoundingBox(context); + _width = FXSYS_round(r.size.width); + _height = FXSYS_round(r.size.height); + _renderCaps = FXRC_SOFT_CLIP | FXRC_BLEND_MODE | FXRC_ALPHA_PATH | + FXRC_ALPHA_IMAGE | FXRC_BIT_MASK | FXRC_ALPHA_MASK; + if (_deviceClass != FXDC_DISPLAY) { + } else { + CGImageRef image = CGBitmapContextCreateImage(_context); + if (image) { + _renderCaps |= FXRC_GET_BITS; + _width = CGImageGetWidth(image); + _height = CGImageGetHeight(image); + CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(image); + if (kCGImageAlphaPremultipliedFirst == alphaInfo || + kCGImageAlphaPremultipliedLast == alphaInfo || + kCGImageAlphaOnly == alphaInfo) { + _renderCaps |= FXRC_ALPHA_OUTPUT; + } } - _foxitDevice2User = CGAffineTransformIdentity; - _user2FoxitDevice = CGAffineTransformInvert(_foxitDevice2User); + CGImageRelease(image); + } + CGAffineTransform ctm = CGContextGetCTM(_context); + CGContextSaveGState(_context); + m_saveCount++; + if (ctm.d >= 0) { + CGFloat offset_x, offset_y; + offset_x = ctm.tx; + offset_y = ctm.ty; + CGContextTranslateCTM(_context, -offset_x, -offset_y); + CGContextConcatCTM(_context, CGAffineTransformMake(1, 0, 0, -1, offset_x, + _height + offset_y)); + } + _foxitDevice2User = CGAffineTransformIdentity; + _user2FoxitDevice = CGAffineTransformInvert(_foxitDevice2User); } -CFX_QuartzDeviceDriver::~CFX_QuartzDeviceDriver() -{ +CFX_QuartzDeviceDriver::~CFX_QuartzDeviceDriver() { + CGContextRestoreGState(_context); + m_saveCount--; + for (int i = 0; i < m_saveCount; ++i) { CGContextRestoreGState(_context); - m_saveCount--; - for (int i = 0; i < m_saveCount; ++i) { - CGContextRestoreGState(_context); + } + if (_context) { + CGContextRelease(_context); + } +} +int CFX_QuartzDeviceDriver::GetDeviceCaps(int capsID) { + switch (capsID) { + case FXDC_DEVICE_CLASS: { + return _deviceClass; } - if (_context) { - CGContextRelease(_context); + case FXDC_PIXEL_WIDTH: { + return _width; } -} -int CFX_QuartzDeviceDriver::GetDeviceCaps(int capsID) -{ - switch (capsID) { - case FXDC_DEVICE_CLASS: { - return _deviceClass; - } - case FXDC_PIXEL_WIDTH: { - return _width; - } - case FXDC_PIXEL_HEIGHT: { - return _height; - } - case FXDC_BITS_PIXEL: { - return 32; - } - case FXDC_RENDER_CAPS: { - return _renderCaps; - } - default: { - return 0; - } + case FXDC_PIXEL_HEIGHT: { + return _height; + } + case FXDC_BITS_PIXEL: { + return 32; } + case FXDC_RENDER_CAPS: { + return _renderCaps; + } + default: { return 0; } + } +} +CFX_Matrix CFX_QuartzDeviceDriver::GetCTM() const { + CGAffineTransform ctm = CGContextGetCTM(_context); + return CFX_Matrix(ctm.a, ctm.b, ctm.c, ctm.d, ctm.tx, ctm.ty); } -CFX_Matrix CFX_QuartzDeviceDriver::GetCTM() const -{ - CGAffineTransform ctm = CGContextGetCTM(_context); - return CFX_Matrix(ctm.a, ctm.b, ctm.c, ctm.d, ctm.tx, ctm.ty); +void CFX_QuartzDeviceDriver::SaveState() { + CGContextSaveGState(_context); + m_saveCount++; } -void CFX_QuartzDeviceDriver::SaveState() -{ +void CFX_QuartzDeviceDriver::RestoreState(FX_BOOL isKeepSaved) { + CGContextRestoreGState(_context); + if (isKeepSaved) { CGContextSaveGState(_context); - m_saveCount++; + } else { + m_saveCount--; + } } -void CFX_QuartzDeviceDriver::RestoreState(FX_BOOL isKeepSaved ) -{ - CGContextRestoreGState(_context); - if (isKeepSaved) { - CGContextSaveGState(_context); - } else { - m_saveCount--; - } +FX_BOOL CFX_QuartzDeviceDriver::SetClip_PathFill(const CFX_PathData* pathData, + const CFX_AffineMatrix* matrix, + int fillMode) { + SaveState(); + CGAffineTransform m = CGAffineTransformIdentity; + if (matrix) { + m = CGAffineTransformMake(matrix->GetA(), matrix->GetB(), matrix->GetC(), + matrix->GetD(), matrix->GetE(), matrix->GetF()); + } + m = CGAffineTransformConcat(m, _foxitDevice2User); + CGContextConcatCTM(_context, m); + setPathToContext(pathData); + RestoreState(FALSE); + if ((fillMode & 3) == FXFILL_WINDING) { + CGContextClip(_context); + } else { + CGContextEOClip(_context); + } + return TRUE; } -FX_BOOL CFX_QuartzDeviceDriver::SetClip_PathFill(const CFX_PathData* pathData, - const CFX_AffineMatrix* matrix, - int fillMode ) -{ - SaveState(); - CGAffineTransform m = CGAffineTransformIdentity; - if (matrix) { - m = CGAffineTransformMake(matrix->GetA(), matrix->GetB(), matrix->GetC(), matrix->GetD(), matrix->GetE(), matrix->GetF()); - } - m = CGAffineTransformConcat(m, _foxitDevice2User); - CGContextConcatCTM(_context, m); - setPathToContext(pathData); - RestoreState(FALSE); - if ((fillMode & 3) == FXFILL_WINDING) { - CGContextClip(_context); - } else { - CGContextEOClip(_context); - } - return TRUE; +FX_FLOAT CFX_QuartzDeviceDriver::getLineWidth( + const CFX_GraphStateData* graphState, + CGAffineTransform ctm) { + FX_FLOAT lineWidth = graphState->m_LineWidth; + if (graphState->m_LineWidth <= 0.f) { + CGSize size; + size.width = 1; + size.height = 1; + CGSize temp = CGSizeApplyAffineTransform(size, ctm); + CGFloat x = 1 / temp.width; + CGFloat y = 1 / temp.height; + lineWidth = x > y ? x : y; + } + return lineWidth; } -FX_FLOAT CFX_QuartzDeviceDriver::getLineWidth(const CFX_GraphStateData * graphState, CGAffineTransform ctm) -{ - FX_FLOAT lineWidth = graphState->m_LineWidth; - if (graphState->m_LineWidth <= 0.f) { - CGSize size; - size.width = 1; - size.height = 1; - CGSize temp = CGSizeApplyAffineTransform(size, ctm); - CGFloat x = 1 / temp.width; - CGFloat y = 1 / temp.height; - lineWidth = x > y ? x : y; - } - return lineWidth; +FX_BOOL CFX_QuartzDeviceDriver::SetClip_PathStroke( + const CFX_PathData* pathData, + const CFX_AffineMatrix* matrix, + const CFX_GraphStateData* graphState) { + SaveState(); + CGAffineTransform m = CGAffineTransformIdentity; + if (matrix) { + m = CGAffineTransformMake(matrix->GetA(), matrix->GetB(), matrix->GetC(), + matrix->GetD(), matrix->GetE(), matrix->GetF()); + } + m = CGAffineTransformConcat(m, _foxitDevice2User); + CGContextConcatCTM(_context, m); + FX_FLOAT lineWidth = getLineWidth(graphState, m); + setStrokeInfo(graphState, 0xFF000000, lineWidth); + setPathToContext(pathData); + CGContextReplacePathWithStrokedPath(_context); + RestoreState(FALSE); + CGContextClip(_context); + return TRUE; } -FX_BOOL CFX_QuartzDeviceDriver::SetClip_PathStroke(const CFX_PathData* pathData, - const CFX_AffineMatrix* matrix, - const CFX_GraphStateData* graphState ) -{ - SaveState(); - CGAffineTransform m = CGAffineTransformIdentity; - if (matrix) { - m = CGAffineTransformMake(matrix->GetA(), matrix->GetB(), matrix->GetC(), matrix->GetD(), matrix->GetE(), matrix->GetF()); - } - m = CGAffineTransformConcat(m, _foxitDevice2User); - CGContextConcatCTM(_context, m); - FX_FLOAT lineWidth = getLineWidth(graphState, m); - setStrokeInfo(graphState, 0xFF000000, lineWidth); - setPathToContext(pathData); - CGContextReplacePathWithStrokedPath(_context); - RestoreState(FALSE); - CGContextClip(_context); - return TRUE; +static CGBlendMode GetCGBlendMode(int blend_type) { + CGBlendMode mode = kCGBlendModeNormal; + switch (blend_type) { + case FXDIB_BLEND_NORMAL: + mode = kCGBlendModeNormal; + break; + case FXDIB_BLEND_MULTIPLY: + mode = kCGBlendModeMultiply; + break; + case FXDIB_BLEND_SCREEN: + mode = kCGBlendModeScreen; + break; + case FXDIB_BLEND_OVERLAY: + mode = kCGBlendModeOverlay; + break; + case FXDIB_BLEND_DARKEN: + mode = kCGBlendModeDarken; + break; + case FXDIB_BLEND_LIGHTEN: + mode = kCGBlendModeLighten; + break; + case FXDIB_BLEND_COLORDODGE: + mode = kCGBlendModeColorDodge; + break; + case FXDIB_BLEND_COLORBURN: + mode = kCGBlendModeColorBurn; + break; + case FXDIB_BLEND_HARDLIGHT: + mode = kCGBlendModeHardLight; + break; + case FXDIB_BLEND_SOFTLIGHT: + mode = kCGBlendModeSoftLight; + break; + case FXDIB_BLEND_DIFFERENCE: + mode = kCGBlendModeDifference; + break; + case FXDIB_BLEND_EXCLUSION: + mode = kCGBlendModeExclusion; + break; + case FXDIB_BLEND_HUE: + mode = kCGBlendModeHue; + break; + case FXDIB_BLEND_SATURATION: + mode = kCGBlendModeSaturation; + break; + case FXDIB_BLEND_COLOR: + mode = kCGBlendModeColor; + break; + case FXDIB_BLEND_LUMINOSITY: + mode = kCGBlendModeLuminosity; + break; + default: + mode = kCGBlendModeNormal; + break; + } + return mode; } -static CGBlendMode GetCGBlendMode(int blend_type) -{ - CGBlendMode mode = kCGBlendModeNormal; - switch (blend_type) { - case FXDIB_BLEND_NORMAL: - mode = kCGBlendModeNormal; - break; - case FXDIB_BLEND_MULTIPLY: - mode = kCGBlendModeMultiply; - break; - case FXDIB_BLEND_SCREEN: - mode = kCGBlendModeScreen; - break; - case FXDIB_BLEND_OVERLAY: - mode = kCGBlendModeOverlay; - break; - case FXDIB_BLEND_DARKEN: - mode = kCGBlendModeDarken; - break; - case FXDIB_BLEND_LIGHTEN: - mode = kCGBlendModeLighten; - break; - case FXDIB_BLEND_COLORDODGE: - mode = kCGBlendModeColorDodge; - break; - case FXDIB_BLEND_COLORBURN: - mode = kCGBlendModeColorBurn; - break; - case FXDIB_BLEND_HARDLIGHT: - mode = kCGBlendModeHardLight; - break; - case FXDIB_BLEND_SOFTLIGHT: - mode = kCGBlendModeSoftLight; - break; - case FXDIB_BLEND_DIFFERENCE: - mode = kCGBlendModeDifference; - break; - case FXDIB_BLEND_EXCLUSION: - mode = kCGBlendModeExclusion; - break; - case FXDIB_BLEND_HUE: - mode = kCGBlendModeHue; - break; - case FXDIB_BLEND_SATURATION: - mode = kCGBlendModeSaturation; - break; - case FXDIB_BLEND_COLOR: - mode = kCGBlendModeColor; - break; - case FXDIB_BLEND_LUMINOSITY: - mode = kCGBlendModeLuminosity; - break; - default: - mode = kCGBlendModeNormal; - break; - } - return mode; +FX_BOOL CFX_QuartzDeviceDriver::DrawPath(const CFX_PathData* pathData, + const CFX_AffineMatrix* matrix, + const CFX_GraphStateData* graphState, + FX_DWORD fillArgb, + FX_DWORD strokeArgb, + int fillMode, + int alpha_flag, + void* pIccTransform, + int blend_type) { + SaveState(); + CGBlendMode mode = GetCGBlendMode(blend_type); + if (mode != kCGBlendModeNormal) { + CGContextSetBlendMode(_context, mode); + } + CGAffineTransform m = CGAffineTransformIdentity; + if (matrix) { + m = CGAffineTransformMake(matrix->GetA(), matrix->GetB(), matrix->GetC(), + matrix->GetD(), matrix->GetE(), matrix->GetF()); + } + m = CGAffineTransformConcat(m, _foxitDevice2User); + CGContextConcatCTM(_context, m); + int pathMode = 0; + if (graphState && strokeArgb) { + CGContextSetMiterLimit(_context, graphState->m_MiterLimit); + FX_FLOAT lineWidth = getLineWidth(graphState, m); + setStrokeInfo(graphState, strokeArgb, lineWidth); + pathMode |= 4; + } + if (fillMode && fillArgb) { + setFillInfo(fillArgb); + if ((fillMode & 3) == FXFILL_WINDING) { + pathMode |= 1; + } else if ((fillMode & 3) == FXFILL_ALTERNATE) { + pathMode |= 2; + } + } + setPathToContext(pathData); + if (fillMode & FXFILL_FULLCOVER) { + CGContextSetShouldAntialias(_context, false); + } + if (pathMode == 4) { + CGContextStrokePath(_context); + } else if (pathMode == 1) { + CGContextFillPath(_context); + } else if (pathMode == 2) { + CGContextEOFillPath(_context); + } else if (pathMode == 5) { + CGContextDrawPath(_context, kCGPathFillStroke); + } else if (pathMode == 6) { + CGContextDrawPath(_context, kCGPathEOFillStroke); + } + RestoreState(FALSE); + return TRUE; } -FX_BOOL CFX_QuartzDeviceDriver::DrawPath(const CFX_PathData* pathData, - const CFX_AffineMatrix* matrix, - const CFX_GraphStateData* graphState, - FX_DWORD fillArgb, - FX_DWORD strokeArgb, - int fillMode, - int alpha_flag, - void* pIccTransform, - int blend_type - ) -{ - SaveState(); - CGBlendMode mode = GetCGBlendMode(blend_type); - if (mode != kCGBlendModeNormal) { - CGContextSetBlendMode(_context, mode); - } - CGAffineTransform m = CGAffineTransformIdentity; - if (matrix) { - m = CGAffineTransformMake(matrix->GetA(), matrix->GetB(), matrix->GetC(), matrix->GetD(), matrix->GetE(), matrix->GetF()); - } - m = CGAffineTransformConcat(m, _foxitDevice2User); - CGContextConcatCTM(_context, m); - int pathMode = 0; - if (graphState && strokeArgb) { - CGContextSetMiterLimit(_context, graphState->m_MiterLimit); - FX_FLOAT lineWidth = getLineWidth(graphState, m); - setStrokeInfo(graphState, strokeArgb, lineWidth); - pathMode |= 4; - } - if (fillMode && fillArgb) { - setFillInfo(fillArgb); - if ((fillMode & 3) == FXFILL_WINDING) { - pathMode |= 1; - } else if ((fillMode & 3) == FXFILL_ALTERNATE) { - pathMode |= 2; - } - } - setPathToContext(pathData); - if (fillMode & FXFILL_FULLCOVER) { - CGContextSetShouldAntialias(_context, false); - } - if (pathMode == 4) { - CGContextStrokePath(_context); - } else if (pathMode == 1) { - CGContextFillPath(_context); - } else if (pathMode == 2) { - CGContextEOFillPath(_context); - } else if (pathMode == 5) { - CGContextDrawPath(_context, kCGPathFillStroke); - } else if (pathMode == 6) { - CGContextDrawPath(_context, kCGPathEOFillStroke); - } - RestoreState(FALSE); - return TRUE; +FX_BOOL CFX_QuartzDeviceDriver::FillRect(const FX_RECT* rect, + FX_ARGB fillArgb, + int alphaFlag, + void* iccTransform, + int blend_type) { + CGBlendMode mode = GetCGBlendMode(blend_type); + if (mode != kCGBlendModeNormal) { + CGContextSetBlendMode(_context, mode); + } + CGRect rect_fx = + CGRectMake(rect->left, rect->top, rect->Width(), rect->Height()); + CGRect rect_usr = CGRectApplyAffineTransform(rect_fx, _foxitDevice2User); + int32_t a, r, g, b; + ArgbDecode(fillArgb, a, r, g, b); + CGContextSetRGBFillColor(_context, r / 255.f, g / 255.f, b / 255.f, + a / 255.f); + CGContextFillRect(_context, rect_usr); + if (mode != kCGBlendModeNormal) { + CGContextSetBlendMode(_context, kCGBlendModeNormal); + } + return TRUE; } -FX_BOOL CFX_QuartzDeviceDriver::FillRect(const FX_RECT* rect, - FX_ARGB fillArgb, - int alphaFlag , - void* iccTransform , - int blend_type ) -{ - CGBlendMode mode = GetCGBlendMode(blend_type); - if (mode != kCGBlendModeNormal) { - CGContextSetBlendMode(_context, mode); - } - CGRect rect_fx = CGRectMake(rect->left, rect->top, rect->Width(), rect->Height()); - CGRect rect_usr = CGRectApplyAffineTransform(rect_fx, _foxitDevice2User); - int32_t a, r, g, b; - ArgbDecode(fillArgb, a, r, g, b); - CGContextSetRGBFillColor(_context, - r / 255.f, - g / 255.f, - b / 255.f, +FX_BOOL CFX_QuartzDeviceDriver::DrawCosmeticLine(FX_FLOAT x1, + FX_FLOAT y1, + FX_FLOAT x2, + FX_FLOAT y2, + FX_DWORD argb, + int alphaFlag, + void* iccTransform, + int blend_type) { + CGBlendMode mode = GetCGBlendMode(blend_type); + if (mode != kCGBlendModeNormal) { + CGContextSetBlendMode(_context, mode); + } + CGPoint pt = + CGPointApplyAffineTransform(CGPointMake(x1, y1), _foxitDevice2User); + x1 = pt.x; + y1 = pt.y; + pt = CGPointApplyAffineTransform(CGPointMake(x2, y2), _foxitDevice2User); + x2 = pt.x; + y2 = pt.y; + int32_t a, r, g, b; + ArgbDecode(argb, a, r, g, b); + CGContextSetRGBStrokeColor(_context, r / 255.f, g / 255.f, b / 255.f, a / 255.f); - CGContextFillRect(_context, rect_usr); - if (mode != kCGBlendModeNormal) { - CGContextSetBlendMode(_context, kCGBlendModeNormal); - } - return TRUE; + CGContextMoveToPoint(_context, x1, y1); + CGContextAddLineToPoint(_context, x2, y2); + CGContextStrokePath(_context); + if (mode != kCGBlendModeNormal) { + CGContextSetBlendMode(_context, kCGBlendModeNormal); + } + return TRUE; } -FX_BOOL CFX_QuartzDeviceDriver::DrawCosmeticLine(FX_FLOAT x1, - FX_FLOAT y1, - FX_FLOAT x2, - FX_FLOAT y2, - FX_DWORD argb, - int alphaFlag , - void* iccTransform , - int blend_type ) -{ - CGBlendMode mode = GetCGBlendMode(blend_type); - if (mode != kCGBlendModeNormal) { - CGContextSetBlendMode(_context, mode); - } - CGPoint pt = CGPointApplyAffineTransform(CGPointMake(x1, y1), _foxitDevice2User); - x1 = pt.x; - y1 = pt.y; - pt = CGPointApplyAffineTransform(CGPointMake(x2, y2), _foxitDevice2User); - x2 = pt.x; - y2 = pt.y; - int32_t a, r, g, b; - ArgbDecode(argb, a, r, g, b); - CGContextSetRGBStrokeColor(_context, - r / 255.f, - g / 255.f, - b / 255.f, - a / 255.f); - CGContextMoveToPoint(_context, x1, y1); - CGContextAddLineToPoint(_context, x2, y2); - CGContextStrokePath(_context); - if (mode != kCGBlendModeNormal) { - CGContextSetBlendMode(_context, kCGBlendModeNormal); - } - return TRUE; -} -FX_BOOL CFX_QuartzDeviceDriver::GetClipBox(FX_RECT* rect) -{ - CGRect r = CGContextGetClipBoundingBox(_context); - r = CGRectApplyAffineTransform(r, _user2FoxitDevice); - rect->left = FXSYS_floor(r.origin.x); - rect->top = FXSYS_floor(r.origin.y); - rect->right = FXSYS_ceil(r.origin.x + r.size.width); - rect->bottom = FXSYS_ceil(r.origin.y + r.size.height); - return TRUE; +FX_BOOL CFX_QuartzDeviceDriver::GetClipBox(FX_RECT* rect) { + CGRect r = CGContextGetClipBoundingBox(_context); + r = CGRectApplyAffineTransform(r, _user2FoxitDevice); + rect->left = FXSYS_floor(r.origin.x); + rect->top = FXSYS_floor(r.origin.y); + rect->right = FXSYS_ceil(r.origin.x + r.size.width); + rect->bottom = FXSYS_ceil(r.origin.y + r.size.height); + return TRUE; } -FX_BOOL CFX_QuartzDeviceDriver::GetDIBits(CFX_DIBitmap* bitmap, - int32_t left, - int32_t top, - void* pIccTransform, - FX_BOOL bDEdge) -{ - if (FXDC_PRINTER == _deviceClass) { - return FALSE; - } - if (bitmap->GetBPP() < 32) { - return FALSE; - } - if (!(_renderCaps | FXRC_GET_BITS)) { - return FALSE; - } - CGPoint pt = CGPointMake(left, top); - pt = CGPointApplyAffineTransform(pt, _foxitDevice2User); - CGAffineTransform ctm = CGContextGetCTM(_context); - pt.x *= FXSYS_fabs(ctm.a); - pt.y *= FXSYS_fabs(ctm.d); - CGImageRef image = CGBitmapContextCreateImage(_context); - if (NULL == image) { - return FALSE; - } - CGFloat width = (CGFloat) bitmap->GetWidth(); - CGFloat height = (CGFloat) bitmap->GetHeight(); - if (width + pt.x > _width) { - width -= (width + pt.x - _width); - } - if (height + pt.y > _height) { - height -= (height + pt.y - _height); - } - CGImageRef subImage = CGImageCreateWithImageInRect(image, - CGRectMake(pt.x, - pt.y, - width, - height)); - CGContextRef context = createContextWithBitmap(bitmap); - CGRect rect = CGContextGetClipBoundingBox(context); - CGContextClearRect(context, rect); - CGContextDrawImage(context, rect, subImage); - CGContextRelease(context); - CGImageRelease(subImage); - CGImageRelease(image); - if (bitmap->HasAlpha()) { - for (int row = 0; row < bitmap->GetHeight(); row ++) { - uint8_t* pScanline = (uint8_t*)bitmap->GetScanline(row); - for (int col = 0; col < bitmap->GetWidth(); col ++) { - if (pScanline[3] > 0) { - pScanline[0] = (pScanline[0] * 255.f / pScanline[3] + .5f); - pScanline[1] = (pScanline[1] * 255.f / pScanline[3] + .5f); - pScanline[2] = (pScanline[2] * 255.f / pScanline[3] + .5f); - } - pScanline += 4; - } +FX_BOOL CFX_QuartzDeviceDriver::GetDIBits(CFX_DIBitmap* bitmap, + int32_t left, + int32_t top, + void* pIccTransform, + FX_BOOL bDEdge) { + if (FXDC_PRINTER == _deviceClass) { + return FALSE; + } + if (bitmap->GetBPP() < 32) { + return FALSE; + } + if (!(_renderCaps | FXRC_GET_BITS)) { + return FALSE; + } + CGPoint pt = CGPointMake(left, top); + pt = CGPointApplyAffineTransform(pt, _foxitDevice2User); + CGAffineTransform ctm = CGContextGetCTM(_context); + pt.x *= FXSYS_fabs(ctm.a); + pt.y *= FXSYS_fabs(ctm.d); + CGImageRef image = CGBitmapContextCreateImage(_context); + if (NULL == image) { + return FALSE; + } + CGFloat width = (CGFloat)bitmap->GetWidth(); + CGFloat height = (CGFloat)bitmap->GetHeight(); + if (width + pt.x > _width) { + width -= (width + pt.x - _width); + } + if (height + pt.y > _height) { + height -= (height + pt.y - _height); + } + CGImageRef subImage = CGImageCreateWithImageInRect( + image, CGRectMake(pt.x, pt.y, width, height)); + CGContextRef context = createContextWithBitmap(bitmap); + CGRect rect = CGContextGetClipBoundingBox(context); + CGContextClearRect(context, rect); + CGContextDrawImage(context, rect, subImage); + CGContextRelease(context); + CGImageRelease(subImage); + CGImageRelease(image); + if (bitmap->HasAlpha()) { + for (int row = 0; row < bitmap->GetHeight(); row++) { + uint8_t* pScanline = (uint8_t*)bitmap->GetScanline(row); + for (int col = 0; col < bitmap->GetWidth(); col++) { + if (pScanline[3] > 0) { + pScanline[0] = (pScanline[0] * 255.f / pScanline[3] + .5f); + pScanline[1] = (pScanline[1] * 255.f / pScanline[3] + .5f); + pScanline[2] = (pScanline[2] * 255.f / pScanline[3] + .5f); } + pScanline += 4; + } } - return TRUE; + } + return TRUE; } -FX_BOOL CFX_QuartzDeviceDriver::SetDIBits(const CFX_DIBSource* pBitmap, - FX_ARGB argb, - const FX_RECT* srcRect, - int dest_left, - int dest_top, - int blendType, - int alphaFlag , - void* iccTransform ) -{ - SaveState(); - CGFloat src_left, src_top, src_width, src_height; - if (srcRect) { - src_left = srcRect->left; - src_top = srcRect->top; - src_width = srcRect->Width(); - src_height = srcRect->Height(); +FX_BOOL CFX_QuartzDeviceDriver::SetDIBits(const CFX_DIBSource* pBitmap, + FX_ARGB argb, + const FX_RECT* srcRect, + int dest_left, + int dest_top, + int blendType, + int alphaFlag, + void* iccTransform) { + SaveState(); + CGFloat src_left, src_top, src_width, src_height; + if (srcRect) { + src_left = srcRect->left; + src_top = srcRect->top; + src_width = srcRect->Width(); + src_height = srcRect->Height(); + } else { + src_left = src_top = 0; + src_width = pBitmap->GetWidth(); + src_height = pBitmap->GetHeight(); + } + CGAffineTransform ctm = CGContextGetCTM(_context); + CGFloat scale_x = FXSYS_fabs(ctm.a); + CGFloat scale_y = FXSYS_fabs(ctm.d); + src_left /= scale_x; + src_top /= scale_y; + src_width /= scale_x; + src_height /= scale_y; + CGRect rect_fx = CGRectMake(dest_left, dest_top, src_width, src_height); + CGRect rect_usr = CGRectApplyAffineTransform(rect_fx, _foxitDevice2User); + CGContextBeginPath(_context); + CGContextAddRect(_context, rect_usr); + CGContextClip(_context); + rect_usr.size = + CGSizeMake(pBitmap->GetWidth() / scale_x, pBitmap->GetHeight() / scale_y); + rect_usr = CGRectOffset(rect_usr, -src_left, -src_top); + CG_SetImageTransform(dest_left, dest_top, src_width, src_height, &rect_usr); + CFX_DIBitmap* pBitmap1 = NULL; + if (pBitmap->IsAlphaMask()) { + if (pBitmap->GetBuffer()) { + pBitmap1 = (CFX_DIBitmap*)pBitmap; } else { - src_left = src_top = 0; - src_width = pBitmap->GetWidth(); - src_height = pBitmap->GetHeight(); - } - CGAffineTransform ctm = CGContextGetCTM(_context); - CGFloat scale_x = FXSYS_fabs(ctm.a); - CGFloat scale_y = FXSYS_fabs(ctm.d); - src_left /= scale_x; - src_top /= scale_y; - src_width /= scale_x; - src_height /= scale_y; - CGRect rect_fx = CGRectMake(dest_left, dest_top, src_width, src_height); - CGRect rect_usr = CGRectApplyAffineTransform(rect_fx, _foxitDevice2User); - CGContextBeginPath(_context); - CGContextAddRect(_context, rect_usr); - CGContextClip(_context); - rect_usr.size = CGSizeMake(pBitmap->GetWidth() / scale_x, pBitmap->GetHeight() / scale_y); - rect_usr = CGRectOffset(rect_usr, -src_left, -src_top); - CG_SetImageTransform(dest_left, dest_top, src_width, src_height, &rect_usr); - CFX_DIBitmap* pBitmap1 = NULL; - if (pBitmap->IsAlphaMask()) { - if (pBitmap->GetBuffer()) { - pBitmap1 = (CFX_DIBitmap*)pBitmap; - } else { - pBitmap1 = pBitmap->Clone(); - } - if (NULL == pBitmap1) { - RestoreState(FALSE); - return FALSE; - } - CGDataProviderRef pBitmapProvider = CGDataProviderCreateWithData(NULL, - pBitmap1->GetBuffer(), - pBitmap1->GetPitch() * pBitmap1->GetHeight(), - NULL); - CGColorSpaceRef pColorSpace = CGColorSpaceCreateDeviceGray(); - CGBitmapInfo bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrderDefault; - CGImageRef pImage = CGImageCreate(pBitmap1->GetWidth(), - pBitmap1->GetHeight(), - pBitmap1->GetBPP(), - pBitmap1->GetBPP(), - pBitmap1->GetPitch(), - pColorSpace, - bitmapInfo, - pBitmapProvider, NULL, true, - kCGRenderingIntentDefault); - CGContextClipToMask(_context, rect_usr, pImage); - CGContextSetRGBFillColor(_context, - FXARGB_R(argb) / 255.f, - FXARGB_G(argb) / 255.f, - FXARGB_B(argb) / 255.f, - FXARGB_A(argb) / 255.f); - CGContextFillRect(_context, rect_usr); - CGImageRelease(pImage); - CGColorSpaceRelease(pColorSpace); - CGDataProviderRelease(pBitmapProvider); - if (pBitmap1 != pBitmap) { - delete pBitmap1; - } - RestoreState(FALSE); - return TRUE; - } - if (pBitmap->GetBPP() < 32) { - pBitmap1 = pBitmap->CloneConvert(FXDIB_Rgb32); - } else { - if (pBitmap->GetBuffer()) { - pBitmap1 = (CFX_DIBitmap*)pBitmap; - } else { - pBitmap1 = pBitmap->Clone(); - } + pBitmap1 = pBitmap->Clone(); } if (NULL == pBitmap1) { - RestoreState(FALSE); - return FALSE; - } - if (pBitmap1->HasAlpha()) { - if (pBitmap1 == pBitmap) { - pBitmap1 = pBitmap->Clone(); - if (!pBitmap1) { - RestoreState(FALSE); - return FALSE; - } - } - for (int row = 0; row < pBitmap1->GetHeight(); row ++) { - uint8_t* pScanline = (uint8_t*)pBitmap1->GetScanline(row); - for (int col = 0; col < pBitmap1->GetWidth(); col ++) { - pScanline[0] = (uint8_t)(pScanline[0] * pScanline[3] / 255.f + .5f); - pScanline[1] = (uint8_t)(pScanline[1] * pScanline[3] / 255.f + .5f); - pScanline[2] = (uint8_t)(pScanline[2] * pScanline[3] / 255.f + .5f); - pScanline += 4; - } - } - } - CGContextRef ctx = createContextWithBitmap(pBitmap1); - CGImageRef image = CGBitmapContextCreateImage(ctx); - int blend_mode = blendType; - if (FXDIB_BLEND_HARDLIGHT == blendType) { - blend_mode = kCGBlendModeSoftLight; - } else if (FXDIB_BLEND_SOFTLIGHT == blendType) { - blend_mode = kCGBlendModeHardLight; - } else if (blendType >= FXDIB_BLEND_NONSEPARABLE && blendType <= FXDIB_BLEND_LUMINOSITY) { - blend_mode = blendType - 9; - } else if (blendType > FXDIB_BLEND_LUMINOSITY || blendType < 0) { - blend_mode = kCGBlendModeNormal; - } - CGContextSetBlendMode(_context, (CGBlendMode)blend_mode); - CGContextDrawImage(_context, rect_usr, image); - CGImageRelease(image); - CGContextRelease(ctx); + RestoreState(FALSE); + return FALSE; + } + CGDataProviderRef pBitmapProvider = CGDataProviderCreateWithData( + NULL, pBitmap1->GetBuffer(), + pBitmap1->GetPitch() * pBitmap1->GetHeight(), NULL); + CGColorSpaceRef pColorSpace = CGColorSpaceCreateDeviceGray(); + CGBitmapInfo bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrderDefault; + CGImageRef pImage = CGImageCreate( + pBitmap1->GetWidth(), pBitmap1->GetHeight(), pBitmap1->GetBPP(), + pBitmap1->GetBPP(), pBitmap1->GetPitch(), pColorSpace, bitmapInfo, + pBitmapProvider, NULL, true, kCGRenderingIntentDefault); + CGContextClipToMask(_context, rect_usr, pImage); + CGContextSetRGBFillColor(_context, FXARGB_R(argb) / 255.f, + FXARGB_G(argb) / 255.f, FXARGB_B(argb) / 255.f, + FXARGB_A(argb) / 255.f); + CGContextFillRect(_context, rect_usr); + CGImageRelease(pImage); + CGColorSpaceRelease(pColorSpace); + CGDataProviderRelease(pBitmapProvider); if (pBitmap1 != pBitmap) { - delete pBitmap1; + delete pBitmap1; } RestoreState(FALSE); return TRUE; -} -FX_BOOL CFX_QuartzDeviceDriver::StretchDIBits(const CFX_DIBSource* pBitmap, - FX_ARGB argb, - int dest_left, - int dest_top, - int dest_width, - int dest_height, - const FX_RECT* clipRect, - FX_DWORD flags, - int alphaFlag , - void* iccTransform , - int blend_type) -{ - SaveState(); - if (clipRect) { - CGContextBeginPath(_context); - CGRect rect_clip = CGRectMake(clipRect->left, clipRect->top, clipRect->Width(), clipRect->Height()); - rect_clip = CGRectApplyAffineTransform(rect_clip, _foxitDevice2User); - CGContextAddRect(_context, rect_clip); - CGContextClip(_context); - } - CGRect rect = CGRectMake(dest_left, dest_top, dest_width, dest_height); - rect = CGRectApplyAffineTransform(rect, _foxitDevice2User); - if (FXDIB_BICUBIC_INTERPOL == flags) { - CGContextSetInterpolationQuality(_context, kCGInterpolationHigh); - } else if (FXDIB_DOWNSAMPLE == flags) { - CGContextSetInterpolationQuality(_context, kCGInterpolationNone); + } + if (pBitmap->GetBPP() < 32) { + pBitmap1 = pBitmap->CloneConvert(FXDIB_Rgb32); + } else { + if (pBitmap->GetBuffer()) { + pBitmap1 = (CFX_DIBitmap*)pBitmap; } else { - CGContextSetInterpolationQuality(_context, kCGInterpolationMedium); + pBitmap1 = pBitmap->Clone(); } - CG_SetImageTransform(dest_left, dest_top, dest_width, dest_height); - CFX_DIBitmap* pBitmap1 = NULL; - if (pBitmap->IsAlphaMask()) { - if (pBitmap->GetBuffer()) { - pBitmap1 = (CFX_DIBitmap*)pBitmap; - } else { - pBitmap1 = pBitmap->Clone(); - } - if (NULL == pBitmap1) { - RestoreState(FALSE); - return FALSE; - } - CGDataProviderRef pBitmapProvider = CGDataProviderCreateWithData(NULL, - pBitmap1->GetBuffer(), - pBitmap1->GetPitch() * pBitmap1->GetHeight(), - NULL); - CGColorSpaceRef pColorSpace = CGColorSpaceCreateDeviceGray(); - CGBitmapInfo bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrderDefault; - CGImageRef pImage = CGImageCreate(pBitmap1->GetWidth(), - pBitmap1->GetHeight(), - pBitmap1->GetBPP(), - pBitmap1->GetBPP(), - pBitmap1->GetPitch(), - pColorSpace, - bitmapInfo, - pBitmapProvider, NULL, true, - kCGRenderingIntentDefault); - CGContextClipToMask(_context, rect, pImage); - CGContextSetRGBFillColor(_context, - FXARGB_R(argb) / 255.f, - FXARGB_G(argb) / 255.f, - FXARGB_B(argb) / 255.f, - FXARGB_A(argb) / 255.f); - CGContextFillRect(_context, rect); - CGImageRelease(pImage); - CGColorSpaceRelease(pColorSpace); - CGDataProviderRelease(pBitmapProvider); - if (pBitmap1 != pBitmap) { - delete pBitmap1; - } + } + if (NULL == pBitmap1) { + RestoreState(FALSE); + return FALSE; + } + if (pBitmap1->HasAlpha()) { + if (pBitmap1 == pBitmap) { + pBitmap1 = pBitmap->Clone(); + if (!pBitmap1) { RestoreState(FALSE); - return TRUE; - } - if (pBitmap->GetBPP() < 32) { - pBitmap1 = pBitmap->CloneConvert(FXDIB_Rgb32); + return FALSE; + } + } + for (int row = 0; row < pBitmap1->GetHeight(); row++) { + uint8_t* pScanline = (uint8_t*)pBitmap1->GetScanline(row); + for (int col = 0; col < pBitmap1->GetWidth(); col++) { + pScanline[0] = (uint8_t)(pScanline[0] * pScanline[3] / 255.f + .5f); + pScanline[1] = (uint8_t)(pScanline[1] * pScanline[3] / 255.f + .5f); + pScanline[2] = (uint8_t)(pScanline[2] * pScanline[3] / 255.f + .5f); + pScanline += 4; + } + } + } + CGContextRef ctx = createContextWithBitmap(pBitmap1); + CGImageRef image = CGBitmapContextCreateImage(ctx); + int blend_mode = blendType; + if (FXDIB_BLEND_HARDLIGHT == blendType) { + blend_mode = kCGBlendModeSoftLight; + } else if (FXDIB_BLEND_SOFTLIGHT == blendType) { + blend_mode = kCGBlendModeHardLight; + } else if (blendType >= FXDIB_BLEND_NONSEPARABLE && + blendType <= FXDIB_BLEND_LUMINOSITY) { + blend_mode = blendType - 9; + } else if (blendType > FXDIB_BLEND_LUMINOSITY || blendType < 0) { + blend_mode = kCGBlendModeNormal; + } + CGContextSetBlendMode(_context, (CGBlendMode)blend_mode); + CGContextDrawImage(_context, rect_usr, image); + CGImageRelease(image); + CGContextRelease(ctx); + if (pBitmap1 != pBitmap) { + delete pBitmap1; + } + RestoreState(FALSE); + return TRUE; +} +FX_BOOL CFX_QuartzDeviceDriver::StretchDIBits(const CFX_DIBSource* pBitmap, + FX_ARGB argb, + int dest_left, + int dest_top, + int dest_width, + int dest_height, + const FX_RECT* clipRect, + FX_DWORD flags, + int alphaFlag, + void* iccTransform, + int blend_type) { + SaveState(); + if (clipRect) { + CGContextBeginPath(_context); + CGRect rect_clip = CGRectMake(clipRect->left, clipRect->top, + clipRect->Width(), clipRect->Height()); + rect_clip = CGRectApplyAffineTransform(rect_clip, _foxitDevice2User); + CGContextAddRect(_context, rect_clip); + CGContextClip(_context); + } + CGRect rect = CGRectMake(dest_left, dest_top, dest_width, dest_height); + rect = CGRectApplyAffineTransform(rect, _foxitDevice2User); + if (FXDIB_BICUBIC_INTERPOL == flags) { + CGContextSetInterpolationQuality(_context, kCGInterpolationHigh); + } else if (FXDIB_DOWNSAMPLE == flags) { + CGContextSetInterpolationQuality(_context, kCGInterpolationNone); + } else { + CGContextSetInterpolationQuality(_context, kCGInterpolationMedium); + } + CG_SetImageTransform(dest_left, dest_top, dest_width, dest_height); + CFX_DIBitmap* pBitmap1 = NULL; + if (pBitmap->IsAlphaMask()) { + if (pBitmap->GetBuffer()) { + pBitmap1 = (CFX_DIBitmap*)pBitmap; } else { - if (pBitmap->GetBuffer()) { - pBitmap1 = (CFX_DIBitmap*)pBitmap; - } else { - pBitmap1 = pBitmap->Clone(); - } + pBitmap1 = pBitmap->Clone(); } if (NULL == pBitmap1) { - RestoreState(FALSE); - return FALSE; - } - if (pBitmap1->HasAlpha()) { - if (pBitmap1 == pBitmap) { - pBitmap1 = pBitmap->Clone(); - if (!pBitmap1) { - RestoreState(FALSE); - return FALSE; - } - } - for (int row = 0; row < pBitmap1->GetHeight(); row ++) { - uint8_t* pScanline = (uint8_t*)pBitmap1->GetScanline(row); - for (int col = 0; col < pBitmap1->GetWidth(); col ++) { - pScanline[0] = (uint8_t)(pScanline[0] * pScanline[3] / 255.f + .5f); - pScanline[1] = (uint8_t)(pScanline[1] * pScanline[3] / 255.f + .5f); - pScanline[2] = (uint8_t)(pScanline[2] * pScanline[3] / 255.f + .5f); - pScanline += 4; - } - } - } - CGContextRef ctx = createContextWithBitmap(pBitmap1); - CGImageRef image = CGBitmapContextCreateImage(ctx); - CGContextDrawImage(_context, rect, image); - CGImageRelease(image); - CGContextRelease(ctx); + RestoreState(FALSE); + return FALSE; + } + CGDataProviderRef pBitmapProvider = CGDataProviderCreateWithData( + NULL, pBitmap1->GetBuffer(), + pBitmap1->GetPitch() * pBitmap1->GetHeight(), NULL); + CGColorSpaceRef pColorSpace = CGColorSpaceCreateDeviceGray(); + CGBitmapInfo bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrderDefault; + CGImageRef pImage = CGImageCreate( + pBitmap1->GetWidth(), pBitmap1->GetHeight(), pBitmap1->GetBPP(), + pBitmap1->GetBPP(), pBitmap1->GetPitch(), pColorSpace, bitmapInfo, + pBitmapProvider, NULL, true, kCGRenderingIntentDefault); + CGContextClipToMask(_context, rect, pImage); + CGContextSetRGBFillColor(_context, FXARGB_R(argb) / 255.f, + FXARGB_G(argb) / 255.f, FXARGB_B(argb) / 255.f, + FXARGB_A(argb) / 255.f); + CGContextFillRect(_context, rect); + CGImageRelease(pImage); + CGColorSpaceRelease(pColorSpace); + CGDataProviderRelease(pBitmapProvider); if (pBitmap1 != pBitmap) { - delete pBitmap1; + delete pBitmap1; } RestoreState(FALSE); return TRUE; -} -FX_BOOL CFX_QuartzDeviceDriver::CG_DrawGlypRun(int nChars, - const FXTEXT_CHARPOS* pCharPos, - CFX_Font* pFont, - CFX_FontCache* pCache, - const CFX_AffineMatrix* pGlyphMatrix, - const CFX_AffineMatrix* pObject2Device, - FX_FLOAT font_size, - FX_DWORD argb, - int alpha_flag, - void* pIccTransform) -{ - if (nChars == 0) { - return TRUE; - } - CQuartz2D& quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d; - if (!pFont->m_pPlatformFont) { - if (pFont->GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) { - return FALSE; - } - pFont->m_pPlatformFont = quartz2d.CreateFont(pFont->m_pFontData, pFont->m_dwSize); - if (NULL == pFont->m_pPlatformFont) { - return FALSE; - } - } - CFX_FixedBufGrow glyph_indices(nChars); - CFX_FixedBufGrow glyph_positions(nChars); - for (int i = 0; i < nChars; i++ ) { - glyph_indices[i] = pCharPos[i].m_ExtGID; - glyph_positions[i].x = pCharPos[i].m_OriginX; - glyph_positions[i].y = pCharPos[i].m_OriginY; - } - CFX_AffineMatrix text_matrix; - if (pObject2Device) { - text_matrix.Concat(*pObject2Device); - } - CGAffineTransform matrix_cg = CGAffineTransformMake(text_matrix.a, - text_matrix.b, - text_matrix.c, - text_matrix.d, - text_matrix.e, - text_matrix.f); - matrix_cg = CGAffineTransformConcat(matrix_cg, _foxitDevice2User); - CGContextSetTextMatrix(_context, matrix_cg); - CGContextSetFont(_context, (CGFontRef)pFont->m_pPlatformFont); - CGContextSetFontSize(_context, FXSYS_fabs(font_size)); - int32_t a, r, g, b; - ArgbDecode(argb, a, r, g, b); - CGContextSetRGBFillColor(_context, - r / 255.f, - g / 255.f, - b / 255.f, - a / 255.f); - SaveState(); - if (pGlyphMatrix) { - CGPoint origin = CGPointMake( glyph_positions[0].x, glyph_positions[0].y); - origin = CGPointApplyAffineTransform(origin, matrix_cg); - CGContextTranslateCTM(_context, origin.x, origin.y); - CGAffineTransform glyph_matrix = CGAffineTransformMake(pGlyphMatrix->a, - pGlyphMatrix->b, - pGlyphMatrix->c, - pGlyphMatrix->d, - pGlyphMatrix->e, - pGlyphMatrix->f); - if (_foxitDevice2User.d < 0) { - glyph_matrix = CGAffineTransformInvert(glyph_matrix); - } - CGContextConcatCTM(_context, glyph_matrix); - CGContextTranslateCTM(_context, -origin.x, -origin.y); + } + if (pBitmap->GetBPP() < 32) { + pBitmap1 = pBitmap->CloneConvert(FXDIB_Rgb32); + } else { + if (pBitmap->GetBuffer()) { + pBitmap1 = (CFX_DIBitmap*)pBitmap; + } else { + pBitmap1 = pBitmap->Clone(); } - CGContextShowGlyphsAtPositions(_context, - (CGGlyph*)glyph_indices, - glyph_positions, - nChars); + } + if (NULL == pBitmap1) { RestoreState(FALSE); + return FALSE; + } + if (pBitmap1->HasAlpha()) { + if (pBitmap1 == pBitmap) { + pBitmap1 = pBitmap->Clone(); + if (!pBitmap1) { + RestoreState(FALSE); + return FALSE; + } + } + for (int row = 0; row < pBitmap1->GetHeight(); row++) { + uint8_t* pScanline = (uint8_t*)pBitmap1->GetScanline(row); + for (int col = 0; col < pBitmap1->GetWidth(); col++) { + pScanline[0] = (uint8_t)(pScanline[0] * pScanline[3] / 255.f + .5f); + pScanline[1] = (uint8_t)(pScanline[1] * pScanline[3] / 255.f + .5f); + pScanline[2] = (uint8_t)(pScanline[2] * pScanline[3] / 255.f + .5f); + pScanline += 4; + } + } + } + CGContextRef ctx = createContextWithBitmap(pBitmap1); + CGImageRef image = CGBitmapContextCreateImage(ctx); + CGContextDrawImage(_context, rect, image); + CGImageRelease(image); + CGContextRelease(ctx); + if (pBitmap1 != pBitmap) { + delete pBitmap1; + } + RestoreState(FALSE); + return TRUE; +} +FX_BOOL CFX_QuartzDeviceDriver::CG_DrawGlypRun( + int nChars, + const FXTEXT_CHARPOS* pCharPos, + CFX_Font* pFont, + CFX_FontCache* pCache, + const CFX_AffineMatrix* pGlyphMatrix, + const CFX_AffineMatrix* pObject2Device, + FX_FLOAT font_size, + FX_DWORD argb, + int alpha_flag, + void* pIccTransform) { + if (nChars == 0) { return TRUE; + } + CQuartz2D& quartz2d = + ((CApplePlatform*)CFX_GEModule::Get()->GetPlatformData())->_quartz2d; + if (!pFont->m_pPlatformFont) { + if (pFont->GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) { + return FALSE; + } + pFont->m_pPlatformFont = + quartz2d.CreateFont(pFont->m_pFontData, pFont->m_dwSize); + if (NULL == pFont->m_pPlatformFont) { + return FALSE; + } + } + CFX_FixedBufGrow glyph_indices(nChars); + CFX_FixedBufGrow glyph_positions(nChars); + for (int i = 0; i < nChars; i++) { + glyph_indices[i] = pCharPos[i].m_ExtGID; + glyph_positions[i].x = pCharPos[i].m_OriginX; + glyph_positions[i].y = pCharPos[i].m_OriginY; + } + CFX_AffineMatrix text_matrix; + if (pObject2Device) { + text_matrix.Concat(*pObject2Device); + } + CGAffineTransform matrix_cg = + CGAffineTransformMake(text_matrix.a, text_matrix.b, text_matrix.c, + text_matrix.d, text_matrix.e, text_matrix.f); + matrix_cg = CGAffineTransformConcat(matrix_cg, _foxitDevice2User); + CGContextSetTextMatrix(_context, matrix_cg); + CGContextSetFont(_context, (CGFontRef)pFont->m_pPlatformFont); + CGContextSetFontSize(_context, FXSYS_fabs(font_size)); + int32_t a, r, g, b; + ArgbDecode(argb, a, r, g, b); + CGContextSetRGBFillColor(_context, r / 255.f, g / 255.f, b / 255.f, + a / 255.f); + SaveState(); + if (pGlyphMatrix) { + CGPoint origin = CGPointMake(glyph_positions[0].x, glyph_positions[0].y); + origin = CGPointApplyAffineTransform(origin, matrix_cg); + CGContextTranslateCTM(_context, origin.x, origin.y); + CGAffineTransform glyph_matrix = CGAffineTransformMake( + pGlyphMatrix->a, pGlyphMatrix->b, pGlyphMatrix->c, pGlyphMatrix->d, + pGlyphMatrix->e, pGlyphMatrix->f); + if (_foxitDevice2User.d < 0) { + glyph_matrix = CGAffineTransformInvert(glyph_matrix); + } + CGContextConcatCTM(_context, glyph_matrix); + CGContextTranslateCTM(_context, -origin.x, -origin.y); + } + CGContextShowGlyphsAtPositions(_context, (CGGlyph*)glyph_indices, + glyph_positions, nChars); + RestoreState(FALSE); + return TRUE; } -FX_BOOL CFX_QuartzDeviceDriver::DrawDeviceText(int nChars, - const FXTEXT_CHARPOS* pCharPos, - CFX_Font* pFont, - CFX_FontCache* pCache, - const CFX_AffineMatrix* pObject2Device, - FX_FLOAT font_size, - FX_DWORD color, - int alpha_flag , - void* pIccTransform) -{ - if (NULL == pFont || NULL == _context) { - return FALSE; - } - FX_BOOL bBold = pFont->IsBold(); - if (!bBold && pFont->GetSubstFont() && - pFont->GetSubstFont()->m_Weight >= 500 && - pFont->GetSubstFont()->m_Weight <= 600) { - return FALSE; - } - SaveState(); - CGContextSetTextDrawingMode(_context, kCGTextFillClip); - FX_BOOL ret = FALSE; - int32_t i = 0; - while (i < nChars) { - if (pCharPos[i].m_bGlyphAdjust || font_size < 0) { - if (i > 0) { - ret = CG_DrawGlypRun(i, pCharPos, pFont, pCache, NULL, pObject2Device, font_size, color, alpha_flag, pIccTransform); - if (!ret) { - RestoreState(FALSE); - return ret; - } - } - const FXTEXT_CHARPOS* char_pos = pCharPos + i; - CFX_AffineMatrix glphy_matrix; - if (font_size < 0) { - glphy_matrix.Concat(-1, 0, 0, -1, 0, 0); - } - if (char_pos->m_bGlyphAdjust) { - glphy_matrix.Concat(char_pos->m_AdjustMatrix[0], - char_pos->m_AdjustMatrix[1], - char_pos->m_AdjustMatrix[2], - char_pos->m_AdjustMatrix[3], 0, 0); - } - ret = CG_DrawGlypRun(1, char_pos, pFont, pCache, &glphy_matrix, pObject2Device, font_size, color, alpha_flag, pIccTransform); - if (!ret) { - RestoreState(FALSE); - return ret; - } - i ++; - pCharPos += i; - nChars -= i; - i = 0; - } else { - i ++; +FX_BOOL CFX_QuartzDeviceDriver::DrawDeviceText( + int nChars, + const FXTEXT_CHARPOS* pCharPos, + CFX_Font* pFont, + CFX_FontCache* pCache, + const CFX_AffineMatrix* pObject2Device, + FX_FLOAT font_size, + FX_DWORD color, + int alpha_flag, + void* pIccTransform) { + if (NULL == pFont || NULL == _context) { + return FALSE; + } + FX_BOOL bBold = pFont->IsBold(); + if (!bBold && pFont->GetSubstFont() && + pFont->GetSubstFont()->m_Weight >= 500 && + pFont->GetSubstFont()->m_Weight <= 600) { + return FALSE; + } + SaveState(); + CGContextSetTextDrawingMode(_context, kCGTextFillClip); + FX_BOOL ret = FALSE; + int32_t i = 0; + while (i < nChars) { + if (pCharPos[i].m_bGlyphAdjust || font_size < 0) { + if (i > 0) { + ret = CG_DrawGlypRun(i, pCharPos, pFont, pCache, NULL, pObject2Device, + font_size, color, alpha_flag, pIccTransform); + if (!ret) { + RestoreState(FALSE); + return ret; } - } - if (i > 0) { - ret = CG_DrawGlypRun(i, pCharPos, pFont, pCache, NULL, pObject2Device, font_size, color, alpha_flag, pIccTransform); - } - RestoreState(FALSE); - return ret; + } + const FXTEXT_CHARPOS* char_pos = pCharPos + i; + CFX_AffineMatrix glphy_matrix; + if (font_size < 0) { + glphy_matrix.Concat(-1, 0, 0, -1, 0, 0); + } + if (char_pos->m_bGlyphAdjust) { + glphy_matrix.Concat( + char_pos->m_AdjustMatrix[0], char_pos->m_AdjustMatrix[1], + char_pos->m_AdjustMatrix[2], char_pos->m_AdjustMatrix[3], 0, 0); + } + ret = CG_DrawGlypRun(1, char_pos, pFont, pCache, &glphy_matrix, + pObject2Device, font_size, color, alpha_flag, + pIccTransform); + if (!ret) { + RestoreState(FALSE); + return ret; + } + i++; + pCharPos += i; + nChars -= i; + i = 0; + } else { + i++; + } + } + if (i > 0) { + ret = CG_DrawGlypRun(i, pCharPos, pFont, pCache, NULL, pObject2Device, + font_size, color, alpha_flag, pIccTransform); + } + RestoreState(FALSE); + return ret; } -void CFX_QuartzDeviceDriver::setStrokeInfo(const CFX_GraphStateData* graphState, FX_ARGB argb, FX_FLOAT lineWidth) -{ - if (NULL == graphState) { - return; - } - CGContextSetLineWidth(_context, lineWidth); - CGLineCap cap; - switch (graphState->m_LineCap) { - case CFX_GraphStateData::LineCapRound: { - cap = kCGLineCapRound; - break; - } - case CFX_GraphStateData::LineCapSquare: { - cap = kCGLineCapSquare; - break; - } - case CFX_GraphStateData::LineCapButt: - default: { - cap = kCGLineCapButt; - } +void CFX_QuartzDeviceDriver::setStrokeInfo(const CFX_GraphStateData* graphState, + FX_ARGB argb, + FX_FLOAT lineWidth) { + if (NULL == graphState) { + return; + } + CGContextSetLineWidth(_context, lineWidth); + CGLineCap cap; + switch (graphState->m_LineCap) { + case CFX_GraphStateData::LineCapRound: { + cap = kCGLineCapRound; + break; + } + case CFX_GraphStateData::LineCapSquare: { + cap = kCGLineCapSquare; + break; + } + case CFX_GraphStateData::LineCapButt: + default: { cap = kCGLineCapButt; } + } + CGContextSetLineCap(_context, cap); + CGLineJoin join; + switch (graphState->m_LineJoin) { + case CFX_GraphStateData::LineJoinRound: { + join = kCGLineJoinRound; + break; + } + case CFX_GraphStateData::LineJoinBevel: { + join = kCGLineJoinBevel; + break; + } + case CFX_GraphStateData::LineJoinMiter: + default: { join = kCGLineJoinMiter; } + } + CGContextSetLineJoin(_context, join); + if (graphState->m_DashCount) { +#if CGFLOAT_IS_DOUBLE + CGFloat* dashArray = new CGFloat[graphState->m_DashCount]; + if (!dashArray) { + return; } - CGContextSetLineCap(_context, cap); - CGLineJoin join; - switch (graphState->m_LineJoin) { - case CFX_GraphStateData::LineJoinRound: { - join = kCGLineJoinRound; - break; - } - case CFX_GraphStateData::LineJoinBevel: { - join = kCGLineJoinBevel; - break; - } - case CFX_GraphStateData::LineJoinMiter: - default: { - join = kCGLineJoinMiter; - } + for (int index = 0; index < graphState->m_DashCount; ++index) { + dashArray[index] = graphState->m_DashArray[index]; } - CGContextSetLineJoin(_context, join); - if (graphState->m_DashCount) { -#if CGFLOAT_IS_DOUBLE - CGFloat* dashArray = new CGFloat[graphState->m_DashCount]; - if (!dashArray) { - return; - } - for (int index = 0; index < graphState->m_DashCount; ++index) { - dashArray[index] = graphState->m_DashArray[index]; - } #else - CGFloat* dashArray = (CGFloat*)graphState->m_DashArray; + CGFloat* dashArray = (CGFloat*)graphState->m_DashArray; #endif - CGContextSetLineDash(_context, graphState->m_DashPhase, dashArray, graphState->m_DashCount); + CGContextSetLineDash(_context, graphState->m_DashPhase, dashArray, + graphState->m_DashCount); #if CGFLOAT_IS_DOUBLE - delete[] dashArray; + delete[] dashArray; #endif - } - int32_t a, r, g, b; - ArgbDecode(argb, a, r, g, b); - CGContextSetRGBStrokeColor(_context, - r / 255.f, - g / 255.f, - b / 255.f, - a / 255.f); -} -void CFX_QuartzDeviceDriver::setFillInfo(FX_ARGB argb) -{ - int32_t a, r, g, b; - ArgbDecode(argb, a, r, g, b); - CGContextSetRGBFillColor(_context, - r / 255.f, - g / 255.f, - b / 255.f, + } + int32_t a, r, g, b; + ArgbDecode(argb, a, r, g, b); + CGContextSetRGBStrokeColor(_context, r / 255.f, g / 255.f, b / 255.f, a / 255.f); } -void CFX_QuartzDeviceDriver::setPathToContext(const CFX_PathData* pathData) -{ - int32_t count = pathData->GetPointCount(); - FX_PATHPOINT* points = pathData->GetPoints(); - CGContextBeginPath(_context); - for (int32_t i = 0; i < count; i ++) { - switch (points[i].m_Flag & FXPT_TYPE) { - case FXPT_MOVETO: - CGContextMoveToPoint(_context, points[i].m_PointX, points[i].m_PointY); - break; - case FXPT_LINETO: - CGContextAddLineToPoint(_context, points[i].m_PointX, points[i].m_PointY); - break; - case FXPT_BEZIERTO: { - CGContextAddCurveToPoint(_context, - points[i].m_PointX, points[i].m_PointY, - points[i + 1].m_PointX, points[i + 1].m_PointY, - points[i + 2].m_PointX, points[i + 2].m_PointY); - i += 2; - } - } - if (points[i].m_Flag & FXPT_CLOSEFIGURE) { - CGContextClosePath(_context); - } - } +void CFX_QuartzDeviceDriver::setFillInfo(FX_ARGB argb) { + int32_t a, r, g, b; + ArgbDecode(argb, a, r, g, b); + CGContextSetRGBFillColor(_context, r / 255.f, g / 255.f, b / 255.f, + a / 255.f); } -void CFX_QuartzDeviceDriver::CG_SetImageTransform(int dest_left, int dest_top, int dest_width, int dest_height, - CGRect* rect ) -{ - int flip_y = _foxitDevice2User.d * dest_height < 0 ? 1 : -1; - int flip_x = _foxitDevice2User.a * dest_width > 0 ? 1 : -1; - if (flip_y < 0 || flip_x < 0) { - if (dest_height < 0) { - dest_height = -dest_height; - dest_top -= dest_height; - } - CGRect rt = CGRectApplyAffineTransform(CGRectMake(dest_left, dest_top, dest_width, dest_height), _foxitDevice2User); - CGFloat offset_x = (rt.origin.x) + rt.size.width / 2.f, - offset_y = (rt.origin.y) + rt.size.height / 2.f; - CGAffineTransform transform = CGAffineTransformIdentity; - transform = CGAffineTransformConcat(transform, CGAffineTransformMake(1, 0, 0, 1, -offset_x, -offset_y)); - transform = CGAffineTransformConcat(transform, CGAffineTransformMake(flip_x, 0, 0, flip_y, 0, 0)); - transform = CGAffineTransformConcat(transform, CGAffineTransformMake(1, 0, 0, 1, offset_x, offset_y)); - CGContextConcatCTM(_context, transform); - if (rect) { - *rect = CGRectApplyAffineTransform(*rect, transform); - } - } +void CFX_QuartzDeviceDriver::setPathToContext(const CFX_PathData* pathData) { + int32_t count = pathData->GetPointCount(); + FX_PATHPOINT* points = pathData->GetPoints(); + CGContextBeginPath(_context); + for (int32_t i = 0; i < count; i++) { + switch (points[i].m_Flag & FXPT_TYPE) { + case FXPT_MOVETO: + CGContextMoveToPoint(_context, points[i].m_PointX, points[i].m_PointY); + break; + case FXPT_LINETO: + CGContextAddLineToPoint(_context, points[i].m_PointX, + points[i].m_PointY); + break; + case FXPT_BEZIERTO: { + CGContextAddCurveToPoint(_context, points[i].m_PointX, + points[i].m_PointY, points[i + 1].m_PointX, + points[i + 1].m_PointY, points[i + 2].m_PointX, + points[i + 2].m_PointY); + i += 2; + } + } + if (points[i].m_Flag & FXPT_CLOSEFIGURE) { + CGContextClosePath(_context); + } + } } -void CFX_QuartzDeviceDriver::ClearDriver() -{ - if (NULL == _context) { - return; - } - for (int i = 0; i < m_saveCount; ++i) { - CGContextRestoreGState(_context); - } - m_saveCount = 0; - if (_context) { - CGContextRelease(_context); - } +void CFX_QuartzDeviceDriver::CG_SetImageTransform(int dest_left, + int dest_top, + int dest_width, + int dest_height, + CGRect* rect) { + int flip_y = _foxitDevice2User.d * dest_height < 0 ? 1 : -1; + int flip_x = _foxitDevice2User.a * dest_width > 0 ? 1 : -1; + if (flip_y < 0 || flip_x < 0) { + if (dest_height < 0) { + dest_height = -dest_height; + dest_top -= dest_height; + } + CGRect rt = CGRectApplyAffineTransform( + CGRectMake(dest_left, dest_top, dest_width, dest_height), + _foxitDevice2User); + CGFloat offset_x = (rt.origin.x) + rt.size.width / 2.f, + offset_y = (rt.origin.y) + rt.size.height / 2.f; + CGAffineTransform transform = CGAffineTransformIdentity; + transform = CGAffineTransformConcat( + transform, CGAffineTransformMake(1, 0, 0, 1, -offset_x, -offset_y)); + transform = CGAffineTransformConcat( + transform, CGAffineTransformMake(flip_x, 0, 0, flip_y, 0, 0)); + transform = CGAffineTransformConcat( + transform, CGAffineTransformMake(1, 0, 0, 1, offset_x, offset_y)); + CGContextConcatCTM(_context, transform); + if (rect) { + *rect = CGRectApplyAffineTransform(*rect, transform); + } + } } -CFX_QuartzDevice::CFX_QuartzDevice() -{ - m_bOwnedBitmap = FALSE; - m_pContext = NULL; +void CFX_QuartzDeviceDriver::ClearDriver() { + if (NULL == _context) { + return; + } + for (int i = 0; i < m_saveCount; ++i) { + CGContextRestoreGState(_context); + } + m_saveCount = 0; + if (_context) { + CGContextRelease(_context); + } } -CFX_QuartzDevice::~CFX_QuartzDevice() -{ - if (m_pContext) { - CGContextRelease(m_pContext); - } - if (m_bOwnedBitmap) { - delete GetBitmap(); - } +CFX_QuartzDevice::CFX_QuartzDevice() { + m_bOwnedBitmap = FALSE; + m_pContext = NULL; } -CGContextRef CFX_QuartzDevice::GetContext() -{ - return m_pContext; +CFX_QuartzDevice::~CFX_QuartzDevice() { + if (m_pContext) { + CGContextRelease(m_pContext); + } + if (m_bOwnedBitmap) { + delete GetBitmap(); + } } -FX_BOOL CFX_QuartzDevice::Attach(CGContextRef context, int32_t nDeviceClass) -{ - if (m_pContext) { - CGContextRelease(m_pContext); - } - m_pContext = context; - CGContextRetain(m_pContext); - IFX_RenderDeviceDriver* pDriver = new CFX_QuartzDeviceDriver(m_pContext, nDeviceClass); - SetDeviceDriver(pDriver); - return TRUE; +CGContextRef CFX_QuartzDevice::GetContext() { + return m_pContext; } -FX_BOOL CFX_QuartzDevice::Attach(CFX_DIBitmap* pBitmap) -{ - SetBitmap(pBitmap); - m_pContext = createContextWithBitmap(pBitmap); - if (NULL == m_pContext) { - return FALSE; - } - IFX_RenderDeviceDriver* pDriver = new CFX_QuartzDeviceDriver(m_pContext, FXDC_DISPLAY); - SetDeviceDriver(pDriver); - return TRUE; +FX_BOOL CFX_QuartzDevice::Attach(CGContextRef context, int32_t nDeviceClass) { + if (m_pContext) { + CGContextRelease(m_pContext); + } + m_pContext = context; + CGContextRetain(m_pContext); + IFX_RenderDeviceDriver* pDriver = + new CFX_QuartzDeviceDriver(m_pContext, nDeviceClass); + SetDeviceDriver(pDriver); + return TRUE; } -FX_BOOL CFX_QuartzDevice::Create(int32_t width, int32_t height, FXDIB_Format format) -{ - if ((uint8_t)format < 32) { - return FALSE; - } - CFX_DIBitmap* pBitmap = new CFX_DIBitmap; - if (!pBitmap->Create(width, height, format)) { - delete pBitmap; - return FALSE; - } - m_bOwnedBitmap = TRUE; - return Attach(pBitmap); +FX_BOOL CFX_QuartzDevice::Attach(CFX_DIBitmap* pBitmap) { + SetBitmap(pBitmap); + m_pContext = createContextWithBitmap(pBitmap); + if (NULL == m_pContext) { + return FALSE; + } + IFX_RenderDeviceDriver* pDriver = + new CFX_QuartzDeviceDriver(m_pContext, FXDC_DISPLAY); + SetDeviceDriver(pDriver); + return TRUE; +} +FX_BOOL CFX_QuartzDevice::Create(int32_t width, + int32_t height, + FXDIB_Format format) { + if ((uint8_t)format < 32) { + return FALSE; + } + CFX_DIBitmap* pBitmap = new CFX_DIBitmap; + if (!pBitmap->Create(width, height, format)) { + delete pBitmap; + return FALSE; + } + m_bOwnedBitmap = TRUE; + return Attach(pBitmap); } #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ diff --git a/core/src/fxge/dib/dib_int.h b/core/src/fxge/dib/dib_int.h index 825cabe1d1..74e77d46da 100644 --- a/core/src/fxge/dib/dib_int.h +++ b/core/src/fxge/dib/dib_int.h @@ -7,87 +7,88 @@ #ifndef CORE_SRC_FXGE_DIB_DIB_INT_H_ #define CORE_SRC_FXGE_DIB_DIB_INT_H_ -class CPDF_FixedMatrix -{ -public: - CPDF_FixedMatrix(const CFX_AffineMatrix& src, int bits) - { - base = 1 << bits; - a = FXSYS_round(src.a * base); - b = FXSYS_round(src.b * base); - c = FXSYS_round(src.c * base); - d = FXSYS_round(src.d * base); - e = FXSYS_round(src.e * base); - f = FXSYS_round(src.f * base); - } - inline void Transform(int x, int y, int& x1, int& y1) - { - x1 = (a * x + c * y + e + base / 2) / base; - y1 = (b * x + d * y + f + base / 2) / base; - } - int a, b, c, d, e, f; - int base; +class CPDF_FixedMatrix { + public: + CPDF_FixedMatrix(const CFX_AffineMatrix& src, int bits) { + base = 1 << bits; + a = FXSYS_round(src.a * base); + b = FXSYS_round(src.b * base); + c = FXSYS_round(src.c * base); + d = FXSYS_round(src.d * base); + e = FXSYS_round(src.e * base); + f = FXSYS_round(src.f * base); + } + inline void Transform(int x, int y, int& x1, int& y1) { + x1 = (a * x + c * y + e + base / 2) / base; + y1 = (b * x + d * y + f + base / 2) / base; + } + int a, b, c, d, e, f; + int base; }; -#define FPDF_HUGE_IMAGE_SIZE 60000000 +#define FPDF_HUGE_IMAGE_SIZE 60000000 struct PixelWeight { - int m_SrcStart; - int m_SrcEnd; - int m_Weights[1]; + int m_SrcStart; + int m_SrcEnd; + int m_Weights[1]; }; -class CWeightTable -{ -public: - CWeightTable() - { - m_pWeightTables = NULL; - } - ~CWeightTable() - { - if(m_pWeightTables) { - FX_Free(m_pWeightTables); - } - m_pWeightTables = NULL; +class CWeightTable { + public: + CWeightTable() { m_pWeightTables = NULL; } + ~CWeightTable() { + if (m_pWeightTables) { + FX_Free(m_pWeightTables); } - void Calc(int dest_len, int dest_min, int dest_max, int src_len, int src_min, int src_max, int flags); - PixelWeight* GetPixelWeight(int pixel) - { - return (PixelWeight*)(m_pWeightTables + (pixel - m_DestMin) * m_ItemSize); - } - int m_DestMin, m_ItemSize; - uint8_t* m_pWeightTables; + m_pWeightTables = NULL; + } + void Calc(int dest_len, + int dest_min, + int dest_max, + int src_len, + int src_min, + int src_max, + int flags); + PixelWeight* GetPixelWeight(int pixel) { + return (PixelWeight*)(m_pWeightTables + (pixel - m_DestMin) * m_ItemSize); + } + int m_DestMin, m_ItemSize; + uint8_t* m_pWeightTables; }; -class CStretchEngine -{ -public: - CStretchEngine(IFX_ScanlineComposer* pDestBitmap, FXDIB_Format dest_format, - int dest_width, int dest_height, const FX_RECT& clip_rect, - const CFX_DIBSource* pSrcBitmap, int flags); - ~CStretchEngine(); - FX_BOOL Continue(IFX_Pause* pPause); -public: - FXDIB_Format m_DestFormat; - int m_DestBpp, m_SrcBpp, m_bHasAlpha; - IFX_ScanlineComposer* m_pDestBitmap; - int m_DestWidth, m_DestHeight; - FX_RECT m_DestClip; - uint8_t* m_pDestScanline; - uint8_t* m_pDestMaskScanline; - FX_RECT m_SrcClip; - const CFX_DIBSource* m_pSource; - FX_DWORD* m_pSrcPalette; - int m_SrcWidth, m_SrcHeight; - int m_SrcPitch, m_InterPitch; - int m_ExtraMaskPitch; - unsigned char* m_pInterBuf; - unsigned char* m_pExtraAlphaBuf; - int m_TransMethod; - int m_Flags; - CWeightTable m_WeightTable; - int m_CurRow; - FX_BOOL StartStretchHorz(); - FX_BOOL ContinueStretchHorz(IFX_Pause* pPause); - void StretchVert(); - int m_State; +class CStretchEngine { + public: + CStretchEngine(IFX_ScanlineComposer* pDestBitmap, + FXDIB_Format dest_format, + int dest_width, + int dest_height, + const FX_RECT& clip_rect, + const CFX_DIBSource* pSrcBitmap, + int flags); + ~CStretchEngine(); + FX_BOOL Continue(IFX_Pause* pPause); + + public: + FXDIB_Format m_DestFormat; + int m_DestBpp, m_SrcBpp, m_bHasAlpha; + IFX_ScanlineComposer* m_pDestBitmap; + int m_DestWidth, m_DestHeight; + FX_RECT m_DestClip; + uint8_t* m_pDestScanline; + uint8_t* m_pDestMaskScanline; + FX_RECT m_SrcClip; + const CFX_DIBSource* m_pSource; + FX_DWORD* m_pSrcPalette; + int m_SrcWidth, m_SrcHeight; + int m_SrcPitch, m_InterPitch; + int m_ExtraMaskPitch; + unsigned char* m_pInterBuf; + unsigned char* m_pExtraAlphaBuf; + int m_TransMethod; + int m_Flags; + CWeightTable m_WeightTable; + int m_CurRow; + FX_BOOL StartStretchHorz(); + FX_BOOL ContinueStretchHorz(IFX_Pause* pPause); + void StretchVert(); + int m_State; }; #endif // CORE_SRC_FXGE_DIB_DIB_INT_H_ diff --git a/core/src/fxge/dib/fx_dib_composite.cpp b/core/src/fxge/dib/fx_dib_composite.cpp index cb99a37ff4..84062d80b1 100644 --- a/core/src/fxge/dib/fx_dib_composite.cpp +++ b/core/src/fxge/dib/fx_dib_composite.cpp @@ -8,4517 +8,5203 @@ #include "../../../include/fxcodec/fx_codec.h" #include "dib_int.h" const uint8_t _color_sqrt[256] = { - 0x00, 0x03, 0x07, 0x0B, 0x0F, 0x12, 0x16, 0x19, 0x1D, 0x20, 0x23, 0x26, 0x29, 0x2C, 0x2F, 0x32, - 0x35, 0x37, 0x3A, 0x3C, 0x3F, 0x41, 0x43, 0x46, 0x48, 0x4A, 0x4C, 0x4E, 0x50, 0x52, 0x54, 0x56, - 0x57, 0x59, 0x5B, 0x5C, 0x5E, 0x60, 0x61, 0x63, 0x64, 0x65, 0x67, 0x68, 0x69, 0x6B, 0x6C, 0x6D, - 0x6E, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, - 0x8F, 0x90, 0x91, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, - 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA4, 0xA5, 0xA6, 0xA7, 0xA7, 0xA8, - 0xA9, 0xAA, 0xAA, 0xAB, 0xAC, 0xAD, 0xAD, 0xAE, 0xAF, 0xB0, 0xB0, 0xB1, 0xB2, 0xB3, 0xB3, 0xB4, - 0xB5, 0xB5, 0xB6, 0xB7, 0xB7, 0xB8, 0xB9, 0xBA, 0xBA, 0xBB, 0xBC, 0xBC, 0xBD, 0xBE, 0xBE, 0xBF, - 0xC0, 0xC0, 0xC1, 0xC2, 0xC2, 0xC3, 0xC4, 0xC4, 0xC5, 0xC6, 0xC6, 0xC7, 0xC7, 0xC8, 0xC9, 0xC9, - 0xCA, 0xCB, 0xCB, 0xCC, 0xCC, 0xCD, 0xCE, 0xCE, 0xCF, 0xD0, 0xD0, 0xD1, 0xD1, 0xD2, 0xD3, 0xD3, - 0xD4, 0xD4, 0xD5, 0xD6, 0xD6, 0xD7, 0xD7, 0xD8, 0xD9, 0xD9, 0xDA, 0xDA, 0xDB, 0xDC, 0xDC, 0xDD, - 0xDD, 0xDE, 0xDE, 0xDF, 0xE0, 0xE0, 0xE1, 0xE1, 0xE2, 0xE2, 0xE3, 0xE4, 0xE4, 0xE5, 0xE5, 0xE6, - 0xE6, 0xE7, 0xE7, 0xE8, 0xE9, 0xE9, 0xEA, 0xEA, 0xEB, 0xEB, 0xEC, 0xEC, 0xED, 0xED, 0xEE, 0xEE, - 0xEF, 0xF0, 0xF0, 0xF1, 0xF1, 0xF2, 0xF2, 0xF3, 0xF3, 0xF4, 0xF4, 0xF5, 0xF5, 0xF6, 0xF6, 0xF7, - 0xF7, 0xF8, 0xF8, 0xF9, 0xF9, 0xFA, 0xFA, 0xFB, 0xFB, 0xFC, 0xFC, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF -}; -int _BLEND(int blend_mode, int back_color, int src_color) -{ - switch (blend_mode) { - case FXDIB_BLEND_NORMAL: - return src_color; - case FXDIB_BLEND_MULTIPLY: - return src_color * back_color / 255; - case FXDIB_BLEND_SCREEN: - return src_color + back_color - src_color * back_color / 255; - case FXDIB_BLEND_OVERLAY: - return _BLEND(FXDIB_BLEND_HARDLIGHT, src_color, back_color); - case FXDIB_BLEND_DARKEN: - return src_color < back_color ? src_color : back_color; - case FXDIB_BLEND_LIGHTEN: - return src_color > back_color ? src_color : back_color; - case FXDIB_BLEND_COLORDODGE: { - if (src_color == 255) { - return src_color; - } - int result = back_color * 255 / (255 - src_color); - if (result > 255) { - return 255; - } - return result; - } - case FXDIB_BLEND_COLORBURN: { - if (src_color == 0) { - return src_color; - } - int result = (255 - back_color) * 255 / src_color; - if (result > 255) { - result = 255; - } - return 255 - result; - } - case FXDIB_BLEND_HARDLIGHT: - if (src_color < 128) { - return (src_color * back_color * 2) / 255; - } - return _BLEND(FXDIB_BLEND_SCREEN, back_color, 2 * src_color - 255); - case FXDIB_BLEND_SOFTLIGHT: { - if (src_color < 128) { - return back_color - (255 - 2 * src_color) * back_color * (255 - back_color) / 255 / 255; - } - return back_color + (2 * src_color - 255) * (_color_sqrt[back_color] - back_color) / 255; - } - case FXDIB_BLEND_DIFFERENCE: - return back_color < src_color ? src_color - back_color : back_color - src_color; - case FXDIB_BLEND_EXCLUSION: - return back_color + src_color - 2 * back_color * src_color / 255; - } - return src_color; + 0x00, 0x03, 0x07, 0x0B, 0x0F, 0x12, 0x16, 0x19, 0x1D, 0x20, 0x23, 0x26, + 0x29, 0x2C, 0x2F, 0x32, 0x35, 0x37, 0x3A, 0x3C, 0x3F, 0x41, 0x43, 0x46, + 0x48, 0x4A, 0x4C, 0x4E, 0x50, 0x52, 0x54, 0x56, 0x57, 0x59, 0x5B, 0x5C, + 0x5E, 0x60, 0x61, 0x63, 0x64, 0x65, 0x67, 0x68, 0x69, 0x6B, 0x6C, 0x6D, + 0x6E, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, + 0x7B, 0x7C, 0x7D, 0x7E, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x91, + 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, + 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA4, 0xA5, + 0xA6, 0xA7, 0xA7, 0xA8, 0xA9, 0xAA, 0xAA, 0xAB, 0xAC, 0xAD, 0xAD, 0xAE, + 0xAF, 0xB0, 0xB0, 0xB1, 0xB2, 0xB3, 0xB3, 0xB4, 0xB5, 0xB5, 0xB6, 0xB7, + 0xB7, 0xB8, 0xB9, 0xBA, 0xBA, 0xBB, 0xBC, 0xBC, 0xBD, 0xBE, 0xBE, 0xBF, + 0xC0, 0xC0, 0xC1, 0xC2, 0xC2, 0xC3, 0xC4, 0xC4, 0xC5, 0xC6, 0xC6, 0xC7, + 0xC7, 0xC8, 0xC9, 0xC9, 0xCA, 0xCB, 0xCB, 0xCC, 0xCC, 0xCD, 0xCE, 0xCE, + 0xCF, 0xD0, 0xD0, 0xD1, 0xD1, 0xD2, 0xD3, 0xD3, 0xD4, 0xD4, 0xD5, 0xD6, + 0xD6, 0xD7, 0xD7, 0xD8, 0xD9, 0xD9, 0xDA, 0xDA, 0xDB, 0xDC, 0xDC, 0xDD, + 0xDD, 0xDE, 0xDE, 0xDF, 0xE0, 0xE0, 0xE1, 0xE1, 0xE2, 0xE2, 0xE3, 0xE4, + 0xE4, 0xE5, 0xE5, 0xE6, 0xE6, 0xE7, 0xE7, 0xE8, 0xE9, 0xE9, 0xEA, 0xEA, + 0xEB, 0xEB, 0xEC, 0xEC, 0xED, 0xED, 0xEE, 0xEE, 0xEF, 0xF0, 0xF0, 0xF1, + 0xF1, 0xF2, 0xF2, 0xF3, 0xF3, 0xF4, 0xF4, 0xF5, 0xF5, 0xF6, 0xF6, 0xF7, + 0xF7, 0xF8, 0xF8, 0xF9, 0xF9, 0xFA, 0xFA, 0xFB, 0xFB, 0xFC, 0xFC, 0xFD, + 0xFD, 0xFE, 0xFE, 0xFF}; +int _BLEND(int blend_mode, int back_color, int src_color) { + switch (blend_mode) { + case FXDIB_BLEND_NORMAL: + return src_color; + case FXDIB_BLEND_MULTIPLY: + return src_color * back_color / 255; + case FXDIB_BLEND_SCREEN: + return src_color + back_color - src_color * back_color / 255; + case FXDIB_BLEND_OVERLAY: + return _BLEND(FXDIB_BLEND_HARDLIGHT, src_color, back_color); + case FXDIB_BLEND_DARKEN: + return src_color < back_color ? src_color : back_color; + case FXDIB_BLEND_LIGHTEN: + return src_color > back_color ? src_color : back_color; + case FXDIB_BLEND_COLORDODGE: { + if (src_color == 255) { + return src_color; + } + int result = back_color * 255 / (255 - src_color); + if (result > 255) { + return 255; + } + return result; + } + case FXDIB_BLEND_COLORBURN: { + if (src_color == 0) { + return src_color; + } + int result = (255 - back_color) * 255 / src_color; + if (result > 255) { + result = 255; + } + return 255 - result; + } + case FXDIB_BLEND_HARDLIGHT: + if (src_color < 128) { + return (src_color * back_color * 2) / 255; + } + return _BLEND(FXDIB_BLEND_SCREEN, back_color, 2 * src_color - 255); + case FXDIB_BLEND_SOFTLIGHT: { + if (src_color < 128) { + return back_color - + (255 - 2 * src_color) * back_color * (255 - back_color) / 255 / + 255; + } + return back_color + + (2 * src_color - 255) * (_color_sqrt[back_color] - back_color) / + 255; + } + case FXDIB_BLEND_DIFFERENCE: + return back_color < src_color ? src_color - back_color + : back_color - src_color; + case FXDIB_BLEND_EXCLUSION: + return back_color + src_color - 2 * back_color * src_color / 255; + } + return src_color; } struct _RGB { - int red; - int green; - int blue; + int red; + int green; + int blue; }; -static inline int _Lum(_RGB color) -{ - return (color.red * 30 + color.green * 59 + color.blue * 11) / 100; +static inline int _Lum(_RGB color) { + return (color.red * 30 + color.green * 59 + color.blue * 11) / 100; } -static _RGB _ClipColor(_RGB color) -{ - int l = _Lum(color); - int n = color.red; - if (color.green < n) { - n = color.green; - } - if (color.blue < n) { - n = color.blue; - } - int x = color.red; - if (color.green > x) { - x = color.green; - } - if (color.blue > x) { - x = color.blue; - } - if (n < 0) { - color.red = l + ((color.red - l) * l / (l - n)); - color.green = l + ((color.green - l) * l / (l - n)); - color.blue = l + ((color.blue - l) * l / (l - n)); - } - if (x > 255) { - color.red = l + ((color.red - l) * (255 - l) / (x - l)); - color.green = l + ((color.green - l) * (255 - l) / (x - l)); - color.blue = l + ((color.blue - l) * (255 - l) / (x - l)); - } - return color; +static _RGB _ClipColor(_RGB color) { + int l = _Lum(color); + int n = color.red; + if (color.green < n) { + n = color.green; + } + if (color.blue < n) { + n = color.blue; + } + int x = color.red; + if (color.green > x) { + x = color.green; + } + if (color.blue > x) { + x = color.blue; + } + if (n < 0) { + color.red = l + ((color.red - l) * l / (l - n)); + color.green = l + ((color.green - l) * l / (l - n)); + color.blue = l + ((color.blue - l) * l / (l - n)); + } + if (x > 255) { + color.red = l + ((color.red - l) * (255 - l) / (x - l)); + color.green = l + ((color.green - l) * (255 - l) / (x - l)); + color.blue = l + ((color.blue - l) * (255 - l) / (x - l)); + } + return color; } -static _RGB _SetLum(_RGB color, int l) -{ - int d = l - _Lum(color); - color.red += d; - color.green += d; - color.blue += d; - return _ClipColor(color); +static _RGB _SetLum(_RGB color, int l) { + int d = l - _Lum(color); + color.red += d; + color.green += d; + color.blue += d; + return _ClipColor(color); } -static int _Sat(_RGB color) -{ - int n = color.red; - if (color.green < n) { - n = color.green; - } - if (color.blue < n) { - n = color.blue; - } - int x = color.red; - if (color.green > x) { - x = color.green; - } - if (color.blue > x) { - x = color.blue; - } - return x - n; +static int _Sat(_RGB color) { + int n = color.red; + if (color.green < n) { + n = color.green; + } + if (color.blue < n) { + n = color.blue; + } + int x = color.red; + if (color.green > x) { + x = color.green; + } + if (color.blue > x) { + x = color.blue; + } + return x - n; } -static _RGB _SetSat(_RGB color, int s) -{ - int* max = &color.red; - int* mid = &color.red; - int* min = &color.red; - if (color.green > *max) { - max = &color.green; - } - if (color.blue > *max) { - max = &color.blue; - } - if (color.green < *min) { - min = &color.green; - } - if (color.blue < *min) { - min = &color.blue; - } - if (*max == *min) { - color.red = 0; - color.green = 0; - color.blue = 0; - return color; - } - if (max == &color.red) { - if (min == &color.green) { - mid = &color.blue; - } else { - mid = &color.green; - } - } else if (max == &color.green) { - if (min == &color.red) { - mid = &color.blue; - } else { - mid = &color.red; - } +static _RGB _SetSat(_RGB color, int s) { + int* max = &color.red; + int* mid = &color.red; + int* min = &color.red; + if (color.green > *max) { + max = &color.green; + } + if (color.blue > *max) { + max = &color.blue; + } + if (color.green < *min) { + min = &color.green; + } + if (color.blue < *min) { + min = &color.blue; + } + if (*max == *min) { + color.red = 0; + color.green = 0; + color.blue = 0; + return color; + } + if (max == &color.red) { + if (min == &color.green) { + mid = &color.blue; } else { - if (min == &color.green) { - mid = &color.red; - } else { - mid = &color.green; - } + mid = &color.green; } - if (*max > *min) { - *mid = (*mid - *min) * s / (*max - *min); - *max = s; - *min = 0; + } else if (max == &color.green) { + if (min == &color.red) { + mid = &color.blue; + } else { + mid = &color.red; } - return color; + } else { + if (min == &color.green) { + mid = &color.red; + } else { + mid = &color.green; + } + } + if (*max > *min) { + *mid = (*mid - *min) * s / (*max - *min); + *max = s; + *min = 0; + } + return color; } -void _RGB_Blend(int blend_mode, const uint8_t* src_scan, uint8_t* dest_scan, int results[3]) -{ - _RGB src, back, result; - src.red = src_scan[2]; - src.green = src_scan[1]; - src.blue = src_scan[0]; - back.red = dest_scan[2]; - back.green = dest_scan[1]; - back.blue = dest_scan[0]; - switch (blend_mode) { - case FXDIB_BLEND_HUE: - result = _SetLum(_SetSat(src, _Sat(back)), _Lum(back)); - break; - case FXDIB_BLEND_SATURATION: - result = _SetLum(_SetSat(back, _Sat(src)), _Lum(back)); - break; - case FXDIB_BLEND_COLOR: - result = _SetLum(src, _Lum(back)); - break; - case FXDIB_BLEND_LUMINOSITY: - result = _SetLum(back, _Lum(src)); - break; - } - results[0] = result.blue; - results[1] = result.green; - results[2] = result.red; +void _RGB_Blend(int blend_mode, + const uint8_t* src_scan, + uint8_t* dest_scan, + int results[3]) { + _RGB src, back, result; + src.red = src_scan[2]; + src.green = src_scan[1]; + src.blue = src_scan[0]; + back.red = dest_scan[2]; + back.green = dest_scan[1]; + back.blue = dest_scan[0]; + switch (blend_mode) { + case FXDIB_BLEND_HUE: + result = _SetLum(_SetSat(src, _Sat(back)), _Lum(back)); + break; + case FXDIB_BLEND_SATURATION: + result = _SetLum(_SetSat(back, _Sat(src)), _Lum(back)); + break; + case FXDIB_BLEND_COLOR: + result = _SetLum(src, _Lum(back)); + break; + case FXDIB_BLEND_LUMINOSITY: + result = _SetLum(back, _Lum(src)); + break; + } + results[0] = result.blue; + results[1] = result.green; + results[2] = result.red; } -inline void _CompositeRow_Argb2Mask(uint8_t* dest_scan, const uint8_t* src_scan, int pixel_count, const uint8_t* clip_scan) -{ - src_scan += 3; - for (int col = 0; col < pixel_count; col ++) { - int src_alpha = *src_scan; - if (clip_scan) { - src_alpha = clip_scan[col] * src_alpha / 255; - } - uint8_t back_alpha = *dest_scan; - if (!back_alpha) { - *dest_scan = src_alpha; - } else if (src_alpha) { - *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255; - } - dest_scan ++; - src_scan += 4; +inline void _CompositeRow_Argb2Mask(uint8_t* dest_scan, + const uint8_t* src_scan, + int pixel_count, + const uint8_t* clip_scan) { + src_scan += 3; + for (int col = 0; col < pixel_count; col++) { + int src_alpha = *src_scan; + if (clip_scan) { + src_alpha = clip_scan[col] * src_alpha / 255; } -} -void _CompositeRow_Rgba2Mask(uint8_t* dest_scan, const uint8_t* src_alpha_scan, int pixel_count, const uint8_t* clip_scan) -{ - for (int col = 0; col < pixel_count; col ++) { - int src_alpha = *src_alpha_scan++; - if (clip_scan) { - src_alpha = clip_scan[col] * src_alpha / 255; - } - uint8_t back_alpha = *dest_scan; - if (!back_alpha) { - *dest_scan = src_alpha; - } else if (src_alpha) { - *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255; - } - dest_scan ++; + uint8_t back_alpha = *dest_scan; + if (!back_alpha) { + *dest_scan = src_alpha; + } else if (src_alpha) { + *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255; } + dest_scan++; + src_scan += 4; + } } -void _CompositeRow_Rgb2Mask(uint8_t* dest_scan, const uint8_t* src_scan, int width, const uint8_t* clip_scan) -{ +void _CompositeRow_Rgba2Mask(uint8_t* dest_scan, + const uint8_t* src_alpha_scan, + int pixel_count, + const uint8_t* clip_scan) { + for (int col = 0; col < pixel_count; col++) { + int src_alpha = *src_alpha_scan++; if (clip_scan) { - for (int i = 0; i < width; i ++) { - *dest_scan = FXDIB_ALPHA_UNION(*dest_scan, *clip_scan); - dest_scan ++; - clip_scan ++; - } - } else { - FXSYS_memset(dest_scan, 0xff, width); - } -} -void _CompositeRow_Argb2Graya(uint8_t* dest_scan, const uint8_t* src_scan, int pixel_count, int blend_type, const uint8_t* clip_scan, - const uint8_t* src_alpha_scan, uint8_t* dst_alpha_scan, void* pIccTransform) -{ - ICodec_IccModule* pIccModule = NULL; - if (pIccTransform) { - pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + src_alpha = clip_scan[col] * src_alpha / 255; } - if (blend_type) { - FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; - int blended_color; - if (src_alpha_scan) { - for (int col = 0; col < pixel_count; col ++) { - uint8_t back_alpha = *dst_alpha_scan; - if (back_alpha == 0) { - int src_alpha = *src_alpha_scan++; - if (clip_scan) { - src_alpha = clip_scan[col] * src_alpha / 255; - } - if (src_alpha) { - if (pIccTransform) { - pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1); - } else { - *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); - } - *dst_alpha_scan = src_alpha; - } - dest_scan ++; - dst_alpha_scan ++; - src_scan += 3; - continue; - } - uint8_t src_alpha = *src_alpha_scan++; - if (clip_scan) { - src_alpha = clip_scan[col] * src_alpha / 255; - } - if (src_alpha == 0) { - dest_scan ++; - dst_alpha_scan ++; - src_scan += 3; - continue; - } - *dst_alpha_scan = FXDIB_ALPHA_UNION(back_alpha, src_alpha); - int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan); - uint8_t gray; - if (pIccTransform) { - pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1); - } else { - gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); - } - if (bNonseparableBlend) { - blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan; - } - gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio); - dest_scan ++; - dst_alpha_scan++; - src_scan += 3; - } - } else - for (int col = 0; col < pixel_count; col ++) { - uint8_t back_alpha = *dst_alpha_scan; - if (back_alpha == 0) { - int src_alpha = src_scan[3]; - if (clip_scan) { - src_alpha = clip_scan[col] * src_alpha / 255; - } - if (src_alpha) { - if (pIccTransform) { - pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1); - } else { - *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); - } - *dst_alpha_scan = src_alpha; - } - dest_scan ++; - dst_alpha_scan ++; - src_scan += 4; - continue; - } - uint8_t src_alpha = src_scan[3]; - if (clip_scan) { - src_alpha = clip_scan[col] * src_alpha / 255; - } - if (src_alpha == 0) { - dest_scan ++; - dst_alpha_scan ++; - src_scan += 4; - continue; - } - *dst_alpha_scan = FXDIB_ALPHA_UNION(back_alpha, src_alpha); - int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan); - uint8_t gray; - if (pIccTransform) { - pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1); - } else { - gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); - } - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio); - dest_scan ++; - dst_alpha_scan++; - src_scan += 4; - } - return; + uint8_t back_alpha = *dest_scan; + if (!back_alpha) { + *dest_scan = src_alpha; + } else if (src_alpha) { + *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255; } + dest_scan++; + } +} +void _CompositeRow_Rgb2Mask(uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + const uint8_t* clip_scan) { + if (clip_scan) { + for (int i = 0; i < width; i++) { + *dest_scan = FXDIB_ALPHA_UNION(*dest_scan, *clip_scan); + dest_scan++; + clip_scan++; + } + } else { + FXSYS_memset(dest_scan, 0xff, width); + } +} +void _CompositeRow_Argb2Graya(uint8_t* dest_scan, + const uint8_t* src_scan, + int pixel_count, + int blend_type, + const uint8_t* clip_scan, + const uint8_t* src_alpha_scan, + uint8_t* dst_alpha_scan, + void* pIccTransform) { + ICodec_IccModule* pIccModule = NULL; + if (pIccTransform) { + pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + } + if (blend_type) { + FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; + int blended_color; if (src_alpha_scan) { - for (int col = 0; col < pixel_count; col ++) { - uint8_t back_alpha = *dst_alpha_scan; - if (back_alpha == 0) { - int src_alpha = *src_alpha_scan++; - if (clip_scan) { - src_alpha = clip_scan[col] * src_alpha / 255; - } - if (src_alpha) { - if (pIccTransform) { - pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1); - } else { - *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); - } - *dst_alpha_scan = src_alpha; - } - dest_scan ++; - dst_alpha_scan ++; - src_scan += 3; - continue; - } - uint8_t src_alpha = *src_alpha_scan++; - if (clip_scan) { - src_alpha = clip_scan[col] * src_alpha / 255; - } - if (src_alpha == 0) { - dest_scan ++; - dst_alpha_scan ++; - src_scan += 3; - continue; - } - *dst_alpha_scan = FXDIB_ALPHA_UNION(back_alpha, src_alpha); - int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan); - uint8_t gray; - if (pIccTransform) { - pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1); - } else { - gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); - } - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio); - dest_scan ++; - dst_alpha_scan++; - src_scan += 3; - } - } else - for (int col = 0; col < pixel_count; col ++) { - uint8_t back_alpha = *dst_alpha_scan; - if (back_alpha == 0) { - int src_alpha = src_scan[3]; - if (clip_scan) { - src_alpha = clip_scan[col] * src_alpha / 255; - } - if (src_alpha) { - if (pIccTransform) { - pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1); - } else { - *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); - } - *dst_alpha_scan = src_alpha; - } - dest_scan ++; - dst_alpha_scan ++; - src_scan += 4; - continue; - } - uint8_t src_alpha = src_scan[3]; - if (clip_scan) { - src_alpha = clip_scan[col] * src_alpha / 255; - } - if (src_alpha == 0) { - dest_scan ++; - dst_alpha_scan ++; - src_scan += 4; - continue; - } - *dst_alpha_scan = FXDIB_ALPHA_UNION(back_alpha, src_alpha); - int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan); - uint8_t gray; + for (int col = 0; col < pixel_count; col++) { + uint8_t back_alpha = *dst_alpha_scan; + if (back_alpha == 0) { + int src_alpha = *src_alpha_scan++; + if (clip_scan) { + src_alpha = clip_scan[col] * src_alpha / 255; + } + if (src_alpha) { if (pIccTransform) { - pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1); + pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, + 1); } else { - gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); - } - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio); - dest_scan ++; - dst_alpha_scan++; - src_scan += 4; - } -} -inline void _CompositeRow_Argb2Gray(uint8_t* dest_scan, const uint8_t* src_scan, int pixel_count, - int blend_type, const uint8_t* clip_scan, - const uint8_t* src_alpha_scan, void* pIccTransform) -{ - ICodec_IccModule* pIccModule = NULL; - uint8_t gray; - if (pIccTransform) { - pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - } - if (blend_type) { - FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; - int blended_color; - if (src_alpha_scan) { - for (int col = 0; col < pixel_count; col ++) { - int src_alpha = *src_alpha_scan++; - if (clip_scan) { - src_alpha = clip_scan[col] * src_alpha / 255; - } - if (src_alpha) { - if (pIccTransform) { - pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1); - } else { - gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); - } - if (bNonseparableBlend) { - blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan; - } - gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha); - } - dest_scan ++; - src_scan += 3; + *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); } - } else - for (int col = 0; col < pixel_count; col ++) { - int src_alpha = src_scan[3]; - if (clip_scan) { - src_alpha = clip_scan[col] * src_alpha / 255; - } - if (src_alpha) { - if (pIccTransform) { - pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1); - } else { - gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); - } - if (bNonseparableBlend) { - blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan; - } - gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha); - } - dest_scan ++; - src_scan += 4; - } - return; - } - if (src_alpha_scan) { - for (int col = 0; col < pixel_count; col ++) { - int src_alpha = *src_alpha_scan++; - if (clip_scan) { - src_alpha = clip_scan[col] * src_alpha / 255; - } - if (src_alpha) { - if (pIccTransform) { - pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1); - } else { - gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); - } - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha); - } - dest_scan ++; - src_scan += 3; + *dst_alpha_scan = src_alpha; + } + dest_scan++; + dst_alpha_scan++; + src_scan += 3; + continue; } - } else - for (int col = 0; col < pixel_count; col ++) { - int src_alpha = src_scan[3]; - if (clip_scan) { - src_alpha = clip_scan[col] * src_alpha / 255; - } - if (src_alpha) { - if (pIccTransform) { - pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1); - } else { - gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); - } - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha); - } - dest_scan ++; - src_scan += 4; + uint8_t src_alpha = *src_alpha_scan++; + if (clip_scan) { + src_alpha = clip_scan[col] * src_alpha / 255; } -} -inline void _CompositeRow_Rgb2Gray(uint8_t* dest_scan, const uint8_t* src_scan, int src_Bpp, int pixel_count, - int blend_type, const uint8_t* clip_scan, - void* pIccTransform) -{ - ICodec_IccModule* pIccModule = NULL; - uint8_t gray; - if (pIccTransform) { - pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - } - if (blend_type) { - FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; - int blended_color; - for (int col = 0; col < pixel_count; col ++) { - if (pIccTransform) { - pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1); - } else { - gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); - } - if (bNonseparableBlend) { - blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan; - } - gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray); - if (clip_scan && clip_scan[col] < 255) { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]); - } else { - *dest_scan = gray; - } - dest_scan ++; - src_scan += src_Bpp; + if (src_alpha == 0) { + dest_scan++; + dst_alpha_scan++; + src_scan += 3; + continue; } - return; - } - for (int col = 0; col < pixel_count; col ++) { + *dst_alpha_scan = FXDIB_ALPHA_UNION(back_alpha, src_alpha); + int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan); + uint8_t gray; if (pIccTransform) { - pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1); + pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1); } else { - gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); + gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); } - if (clip_scan && clip_scan[col] < 255) { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]); - } else { - *dest_scan = gray; + if (bNonseparableBlend) { + blended_color = + blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan; } - dest_scan ++; - src_scan += src_Bpp; - } -} -void _CompositeRow_Rgb2Graya(uint8_t* dest_scan, const uint8_t* src_scan, int src_Bpp, int pixel_count, - int blend_type, const uint8_t* clip_scan, - uint8_t* dest_alpha_scan, void* pIccTransform) -{ - ICodec_IccModule* pIccModule = NULL; - if (pIccTransform) { - pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - } - if (blend_type) { - int blended_color; - FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; - for (int col = 0; col < pixel_count; col ++) { - int back_alpha = *dest_alpha_scan; - if (back_alpha == 0) { - if (pIccTransform) { - pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1); - } else { - *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); - } - dest_scan ++; - dest_alpha_scan++; - src_scan += src_Bpp; - continue; - } - int src_alpha = 255; - if (clip_scan) { - src_alpha = clip_scan[col]; - } - if (src_alpha == 0) { - dest_scan ++; - dest_alpha_scan ++; - src_scan += src_Bpp; - continue; - } - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - *dest_alpha_scan++ = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - uint8_t gray; + gray = bNonseparableBlend ? blended_color + : _BLEND(blend_type, *dest_scan, gray); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio); + dest_scan++; + dst_alpha_scan++; + src_scan += 3; + } + } else + for (int col = 0; col < pixel_count; col++) { + uint8_t back_alpha = *dst_alpha_scan; + if (back_alpha == 0) { + int src_alpha = src_scan[3]; + if (clip_scan) { + src_alpha = clip_scan[col] * src_alpha / 255; + } + if (src_alpha) { if (pIccTransform) { - pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1); + pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, + 1); } else { - gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); - } - if (bNonseparableBlend) { - blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan; + *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); } - gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio); - dest_scan ++; - src_scan += src_Bpp; + *dst_alpha_scan = src_alpha; + } + dest_scan++; + dst_alpha_scan++; + src_scan += 4; + continue; } - return; - } - for (int col = 0; col < pixel_count; col ++) { - int src_alpha = 255; + uint8_t src_alpha = src_scan[3]; if (clip_scan) { - src_alpha = clip_scan[col]; - } - if (src_alpha == 255) { - if (pIccTransform) { - pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1); - } else { - *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); - } - dest_scan ++; - *dest_alpha_scan++ = 255; - src_scan += src_Bpp; - continue; + src_alpha = clip_scan[col] * src_alpha / 255; } if (src_alpha == 0) { - dest_scan ++; - dest_alpha_scan ++; - src_scan += src_Bpp; - continue; + dest_scan++; + dst_alpha_scan++; + src_scan += 4; + continue; } - int back_alpha = *dest_alpha_scan; - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - *dest_alpha_scan++ = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; + *dst_alpha_scan = FXDIB_ALPHA_UNION(back_alpha, src_alpha); + int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan); uint8_t gray; if (pIccTransform) { - pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1); + pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1); } else { - gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); + gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); } *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio); - dest_scan ++; - src_scan += src_Bpp; + dest_scan++; + dst_alpha_scan++; + src_scan += 4; + } + return; + } + if (src_alpha_scan) { + for (int col = 0; col < pixel_count; col++) { + uint8_t back_alpha = *dst_alpha_scan; + if (back_alpha == 0) { + int src_alpha = *src_alpha_scan++; + if (clip_scan) { + src_alpha = clip_scan[col] * src_alpha / 255; + } + if (src_alpha) { + if (pIccTransform) { + pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, + 1); + } else { + *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); + } + *dst_alpha_scan = src_alpha; + } + dest_scan++; + dst_alpha_scan++; + src_scan += 3; + continue; + } + uint8_t src_alpha = *src_alpha_scan++; + if (clip_scan) { + src_alpha = clip_scan[col] * src_alpha / 255; + } + if (src_alpha == 0) { + dest_scan++; + dst_alpha_scan++; + src_scan += 3; + continue; + } + *dst_alpha_scan = FXDIB_ALPHA_UNION(back_alpha, src_alpha); + int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan); + uint8_t gray; + if (pIccTransform) { + pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1); + } else { + gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); + } + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio); + dest_scan++; + dst_alpha_scan++; + src_scan += 3; + } + } else + for (int col = 0; col < pixel_count; col++) { + uint8_t back_alpha = *dst_alpha_scan; + if (back_alpha == 0) { + int src_alpha = src_scan[3]; + if (clip_scan) { + src_alpha = clip_scan[col] * src_alpha / 255; + } + if (src_alpha) { + if (pIccTransform) { + pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, + 1); + } else { + *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); + } + *dst_alpha_scan = src_alpha; + } + dest_scan++; + dst_alpha_scan++; + src_scan += 4; + continue; + } + uint8_t src_alpha = src_scan[3]; + if (clip_scan) { + src_alpha = clip_scan[col] * src_alpha / 255; + } + if (src_alpha == 0) { + dest_scan++; + dst_alpha_scan++; + src_scan += 4; + continue; + } + *dst_alpha_scan = FXDIB_ALPHA_UNION(back_alpha, src_alpha); + int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan); + uint8_t gray; + if (pIccTransform) { + pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1); + } else { + gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); + } + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio); + dest_scan++; + dst_alpha_scan++; + src_scan += 4; } } -void _CompositeRow_Argb2Argb(uint8_t* dest_scan, const uint8_t* src_scan, int pixel_count, int blend_type, const uint8_t* clip_scan, - uint8_t* dest_alpha_scan, const uint8_t* src_alpha_scan) -{ - int blended_colors[3]; +inline void _CompositeRow_Argb2Gray(uint8_t* dest_scan, + const uint8_t* src_scan, + int pixel_count, + int blend_type, + const uint8_t* clip_scan, + const uint8_t* src_alpha_scan, + void* pIccTransform) { + ICodec_IccModule* pIccModule = NULL; + uint8_t gray; + if (pIccTransform) { + pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + } + if (blend_type) { FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; - if (dest_alpha_scan == NULL) { - if (src_alpha_scan == NULL) { - uint8_t back_alpha = 0; - for (int col = 0; col < pixel_count; col ++) { - back_alpha = dest_scan[3]; - if (back_alpha == 0) { - if (clip_scan) { - int src_alpha = clip_scan[col] * src_scan[3] / 255; - FXARGB_SETDIB(dest_scan, (FXARGB_GETDIB(src_scan) & 0xffffff) | (src_alpha << 24)); - } else { - FXARGB_COPY(dest_scan, src_scan); - } - dest_scan += 4; - src_scan += 4; - continue; - } - uint8_t src_alpha; - if (clip_scan == NULL) { - src_alpha = src_scan[3]; - } else { - src_alpha = clip_scan[col] * src_scan[3] / 255; - } - if (src_alpha == 0) { - dest_scan += 4; - src_scan += 4; - continue; - } - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - dest_scan[3] = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - if (bNonseparableBlend) { - _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); - } - for (int color = 0; color < 3; color ++) { - if (blend_type) { - int blended = bNonseparableBlend ? blended_colors[color] : - _BLEND(blend_type, *dest_scan, *src_scan); - blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); - } else { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio); - } - dest_scan ++; - src_scan ++; - } - dest_scan ++; - src_scan ++; - } - } else { - for (int col = 0; col < pixel_count; col ++) { - uint8_t back_alpha = dest_scan[3]; - if (back_alpha == 0) { - if (clip_scan) { - int src_alpha = clip_scan[col] * (*src_alpha_scan) / 255; - FXARGB_SETDIB(dest_scan, FXARGB_MAKE((src_alpha << 24), src_scan[2], src_scan[1], *src_scan)); - } else { - FXARGB_SETDIB(dest_scan, FXARGB_MAKE((*src_alpha_scan << 24), src_scan[2], src_scan[1], *src_scan)); - } - dest_scan += 4; - src_scan += 3; - src_alpha_scan ++; - continue; - } - uint8_t src_alpha; - if (clip_scan == NULL) { - src_alpha = *src_alpha_scan ++; - } else { - src_alpha = clip_scan[col] * (*src_alpha_scan ++) / 255; - } - if (src_alpha == 0) { - dest_scan += 4; - src_scan += 3; - continue; - } - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - dest_scan[3] = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - if (bNonseparableBlend) { - _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); - } - for (int color = 0; color < 3; color ++) { - if (blend_type) { - int blended = bNonseparableBlend ? blended_colors[color] : - _BLEND(blend_type, *dest_scan, *src_scan); - blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); - } else { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio); - } - dest_scan ++; - src_scan ++; - } - dest_scan ++; - } + int blended_color; + if (src_alpha_scan) { + for (int col = 0; col < pixel_count; col++) { + int src_alpha = *src_alpha_scan++; + if (clip_scan) { + src_alpha = clip_scan[col] * src_alpha / 255; } - } else { - if (src_alpha_scan) { - for (int col = 0; col < pixel_count; col ++) { - uint8_t back_alpha = *dest_alpha_scan; - if (back_alpha == 0) { - if (clip_scan) { - int src_alpha = clip_scan[col] * (*src_alpha_scan) / 255; - *dest_alpha_scan = src_alpha; - *dest_scan++ = *src_scan++; - *dest_scan++ = *src_scan++; - *dest_scan++ = *src_scan++; - } else { - *dest_alpha_scan = *src_alpha_scan; - *dest_scan++ = *src_scan++; - *dest_scan++ = *src_scan++; - *dest_scan++ = *src_scan++; - } - dest_alpha_scan ++; - src_alpha_scan ++; - continue; - } - uint8_t src_alpha; - if (clip_scan == NULL) { - src_alpha = *src_alpha_scan ++; - } else { - src_alpha = clip_scan[col] * (*src_alpha_scan ++) / 255; - } - if (src_alpha == 0) { - dest_scan += 3; - src_scan += 3; - dest_alpha_scan ++; - continue; - } - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - *dest_alpha_scan ++ = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - if (bNonseparableBlend) { - _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); - } - for (int color = 0; color < 3; color ++) { - if (blend_type) { - int blended = bNonseparableBlend ? blended_colors[color] : - _BLEND(blend_type, *dest_scan, *src_scan); - blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); - } else { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio); - } - dest_scan ++; - src_scan ++; - } - } + if (src_alpha) { + if (pIccTransform) { + pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1); + } else { + gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); + } + if (bNonseparableBlend) { + blended_color = + blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan; + } + gray = bNonseparableBlend ? blended_color + : _BLEND(blend_type, *dest_scan, gray); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha); + } + dest_scan++; + src_scan += 3; + } + } else + for (int col = 0; col < pixel_count; col++) { + int src_alpha = src_scan[3]; + if (clip_scan) { + src_alpha = clip_scan[col] * src_alpha / 255; + } + if (src_alpha) { + if (pIccTransform) { + pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1); + } else { + gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); + } + if (bNonseparableBlend) { + blended_color = + blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan; + } + gray = bNonseparableBlend ? blended_color + : _BLEND(blend_type, *dest_scan, gray); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha); + } + dest_scan++; + src_scan += 4; + } + return; + } + if (src_alpha_scan) { + for (int col = 0; col < pixel_count; col++) { + int src_alpha = *src_alpha_scan++; + if (clip_scan) { + src_alpha = clip_scan[col] * src_alpha / 255; + } + if (src_alpha) { + if (pIccTransform) { + pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1); } else { - for (int col = 0; col < pixel_count; col ++) { - uint8_t back_alpha = *dest_alpha_scan; - if (back_alpha == 0) { - if (clip_scan) { - int src_alpha = clip_scan[col] * src_scan[3] / 255; - *dest_alpha_scan = src_alpha; - *dest_scan++ = *src_scan++; - *dest_scan++ = *src_scan++; - *dest_scan++ = *src_scan++; - } else { - *dest_alpha_scan = src_scan[3]; - *dest_scan++ = *src_scan++; - *dest_scan++ = *src_scan++; - *dest_scan++ = *src_scan++; - } - dest_alpha_scan ++; - src_scan ++; - continue; - } - uint8_t src_alpha; - if (clip_scan == NULL) { - src_alpha = src_scan[3]; - } else { - src_alpha = clip_scan[col] * src_scan[3] / 255; - } - if (src_alpha == 0) { - dest_scan += 3; - src_scan += 4; - dest_alpha_scan ++; - continue; - } - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - *dest_alpha_scan++ = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - if (bNonseparableBlend) { - _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); - } - for (int color = 0; color < 3; color ++) { - if (blend_type) { - int blended = bNonseparableBlend ? blended_colors[color] : - _BLEND(blend_type, *dest_scan, *src_scan); - blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); - } else { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio); - } - dest_scan ++; - src_scan ++; - } - src_scan ++; - } + gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); + } + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha); + } + dest_scan++; + src_scan += 3; + } + } else + for (int col = 0; col < pixel_count; col++) { + int src_alpha = src_scan[3]; + if (clip_scan) { + src_alpha = clip_scan[col] * src_alpha / 255; + } + if (src_alpha) { + if (pIccTransform) { + pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1); + } else { + gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); } + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha); + } + dest_scan++; + src_scan += 4; } } -void _CompositeRow_Rgb2Argb_Blend_NoClip(uint8_t* dest_scan, const uint8_t* src_scan, int width, int blend_type, int src_Bpp, - uint8_t* dest_alpha_scan) -{ - int blended_colors[3]; +inline void _CompositeRow_Rgb2Gray(uint8_t* dest_scan, + const uint8_t* src_scan, + int src_Bpp, + int pixel_count, + int blend_type, + const uint8_t* clip_scan, + void* pIccTransform) { + ICodec_IccModule* pIccModule = NULL; + uint8_t gray; + if (pIccTransform) { + pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + } + if (blend_type) { FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; - int src_gap = src_Bpp - 3; - if (dest_alpha_scan == NULL) { - for (int col = 0; col < width; col ++) { - uint8_t back_alpha = dest_scan[3]; - if (back_alpha == 0) { - if (src_Bpp == 4) { - FXARGB_SETDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan)); - } else { - FXARGB_SETDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[2], src_scan[1], src_scan[0])); - } - dest_scan += 4; - src_scan += src_Bpp; - continue; - } - dest_scan[3] = 0xff; - if (bNonseparableBlend) { - _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); - } - for (int color = 0; color < 3; color ++) { - int src_color = *src_scan; - int blended = bNonseparableBlend ? blended_colors[color] : - _BLEND(blend_type, *dest_scan, src_color); - *dest_scan = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha); - dest_scan ++; - src_scan ++; - } - dest_scan ++; - src_scan += src_gap; - } + int blended_color; + for (int col = 0; col < pixel_count; col++) { + if (pIccTransform) { + pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1); + } else { + gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); + } + if (bNonseparableBlend) { + blended_color = + blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan; + } + gray = bNonseparableBlend ? blended_color + : _BLEND(blend_type, *dest_scan, gray); + if (clip_scan && clip_scan[col] < 255) { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]); + } else { + *dest_scan = gray; + } + dest_scan++; + src_scan += src_Bpp; + } + return; + } + for (int col = 0; col < pixel_count; col++) { + if (pIccTransform) { + pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1); } else { - for (int col = 0; col < width; col ++) { - uint8_t back_alpha = *dest_alpha_scan; - if (back_alpha == 0) { - *dest_scan++ = *src_scan++; - *dest_scan++ = *src_scan++; - *dest_scan++ = *src_scan++; - *dest_alpha_scan++ = 0xff; - src_scan += src_gap; - continue; - } - *dest_alpha_scan++ = 0xff; - if (bNonseparableBlend) { - _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); - } - for (int color = 0; color < 3; color ++) { - int src_color = *src_scan; - int blended = bNonseparableBlend ? blended_colors[color] : - _BLEND(blend_type, *dest_scan, src_color); - *dest_scan = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha); - dest_scan ++; - src_scan ++; - } - src_scan += src_gap; - } + gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); + } + if (clip_scan && clip_scan[col] < 255) { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]); + } else { + *dest_scan = gray; } + dest_scan++; + src_scan += src_Bpp; + } } -inline void _CompositeRow_Rgb2Argb_Blend_Clip(uint8_t* dest_scan, const uint8_t* src_scan, int width, int blend_type, int src_Bpp, const uint8_t* clip_scan, - uint8_t* dest_alpha_scan) -{ - int blended_colors[3]; +void _CompositeRow_Rgb2Graya(uint8_t* dest_scan, + const uint8_t* src_scan, + int src_Bpp, + int pixel_count, + int blend_type, + const uint8_t* clip_scan, + uint8_t* dest_alpha_scan, + void* pIccTransform) { + ICodec_IccModule* pIccModule = NULL; + if (pIccTransform) { + pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + } + if (blend_type) { + int blended_color; FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; - int src_gap = src_Bpp - 3; - if (dest_alpha_scan == NULL) { - for (int col = 0; col < width; col ++) { - int src_alpha = *clip_scan ++; - uint8_t back_alpha = dest_scan[3]; - if (back_alpha == 0) { - *dest_scan++ = *src_scan++; - *dest_scan++ = *src_scan++; - *dest_scan++ = *src_scan++; - src_scan += src_gap; - dest_scan ++; - continue; - } - if (src_alpha == 0) { - dest_scan += 4; - src_scan += src_Bpp; - continue; - } - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - dest_scan[3] = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - if (bNonseparableBlend) { - _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); - } - for (int color = 0; color < 3; color ++) { - int src_color = *src_scan; - int blended = bNonseparableBlend ? blended_colors[color] : - _BLEND(blend_type, *dest_scan, src_color); - blended = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); - dest_scan ++; - src_scan ++; - } - dest_scan ++; - src_scan += src_gap; + for (int col = 0; col < pixel_count; col++) { + int back_alpha = *dest_alpha_scan; + if (back_alpha == 0) { + if (pIccTransform) { + pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1); + } else { + *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); } + dest_scan++; + dest_alpha_scan++; + src_scan += src_Bpp; + continue; + } + int src_alpha = 255; + if (clip_scan) { + src_alpha = clip_scan[col]; + } + if (src_alpha == 0) { + dest_scan++; + dest_alpha_scan++; + src_scan += src_Bpp; + continue; + } + uint8_t dest_alpha = + back_alpha + src_alpha - back_alpha * src_alpha / 255; + *dest_alpha_scan++ = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + uint8_t gray; + if (pIccTransform) { + pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1); + } else { + gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); + } + if (bNonseparableBlend) { + blended_color = + blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan; + } + gray = bNonseparableBlend ? blended_color + : _BLEND(blend_type, *dest_scan, gray); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio); + dest_scan++; + src_scan += src_Bpp; + } + return; + } + for (int col = 0; col < pixel_count; col++) { + int src_alpha = 255; + if (clip_scan) { + src_alpha = clip_scan[col]; + } + if (src_alpha == 255) { + if (pIccTransform) { + pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1); + } else { + *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); + } + dest_scan++; + *dest_alpha_scan++ = 255; + src_scan += src_Bpp; + continue; + } + if (src_alpha == 0) { + dest_scan++; + dest_alpha_scan++; + src_scan += src_Bpp; + continue; + } + int back_alpha = *dest_alpha_scan; + uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; + *dest_alpha_scan++ = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + uint8_t gray; + if (pIccTransform) { + pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1); } else { - for (int col = 0; col < width; col ++) { - int src_alpha = *clip_scan ++; - uint8_t back_alpha = *dest_alpha_scan; - if (back_alpha == 0) { - *dest_scan++ = *src_scan++; - *dest_scan++ = *src_scan++; - *dest_scan++ = *src_scan++; - src_scan += src_gap; - dest_alpha_scan++; - continue; - } - if (src_alpha == 0) { - dest_scan += 3; - dest_alpha_scan++; - src_scan += src_Bpp; - continue; - } - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - *dest_alpha_scan++ = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - if (bNonseparableBlend) { - _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); - } - for (int color = 0; color < 3; color ++) { - int src_color = *src_scan; - int blended = bNonseparableBlend ? blended_colors[color] : - _BLEND(blend_type, *dest_scan, src_color); - blended = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); - dest_scan ++; - src_scan ++; - } - src_scan += src_gap; - } + gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan); } + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio); + dest_scan++; + src_scan += src_Bpp; + } } -inline void _CompositeRow_Rgb2Argb_NoBlend_Clip(uint8_t* dest_scan, const uint8_t* src_scan, int width, int src_Bpp, const uint8_t* clip_scan, - uint8_t* dest_alpha_scan) -{ - int src_gap = src_Bpp - 3; - if (dest_alpha_scan == NULL) { - for (int col = 0; col < width; col ++) { - int src_alpha = clip_scan[col]; - if (src_alpha == 255) { - *dest_scan++ = *src_scan++; - *dest_scan++ = *src_scan++; - *dest_scan++ = *src_scan++; - *dest_scan++ = 255; - src_scan += src_gap; - continue; - } - if (src_alpha == 0) { - dest_scan += 4; - src_scan += src_Bpp; - continue; - } - int back_alpha = dest_scan[3]; - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - dest_scan[3] = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - for (int color = 0; color < 3; color ++) { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio); - dest_scan ++; - src_scan ++; - } - dest_scan ++; - src_scan += src_gap; +void _CompositeRow_Argb2Argb(uint8_t* dest_scan, + const uint8_t* src_scan, + int pixel_count, + int blend_type, + const uint8_t* clip_scan, + uint8_t* dest_alpha_scan, + const uint8_t* src_alpha_scan) { + int blended_colors[3]; + FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; + if (dest_alpha_scan == NULL) { + if (src_alpha_scan == NULL) { + uint8_t back_alpha = 0; + for (int col = 0; col < pixel_count; col++) { + back_alpha = dest_scan[3]; + if (back_alpha == 0) { + if (clip_scan) { + int src_alpha = clip_scan[col] * src_scan[3] / 255; + FXARGB_SETDIB(dest_scan, (FXARGB_GETDIB(src_scan) & 0xffffff) | + (src_alpha << 24)); + } else { + FXARGB_COPY(dest_scan, src_scan); + } + dest_scan += 4; + src_scan += 4; + continue; } - } else { - for (int col = 0; col < width; col ++) { - int src_alpha = clip_scan[col]; - if (src_alpha == 255) { - *dest_scan++ = *src_scan++; - *dest_scan++ = *src_scan++; - *dest_scan++ = *src_scan++; - *dest_alpha_scan++ = 255; - src_scan += src_gap; - continue; - } - if (src_alpha == 0) { - dest_scan += 3; - dest_alpha_scan ++; - src_scan += src_Bpp; - continue; - } - int back_alpha = *dest_alpha_scan; - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - *dest_alpha_scan ++ = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - for (int color = 0; color < 3; color ++) { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio); - dest_scan ++; - src_scan ++; - } - src_scan += src_gap; + uint8_t src_alpha; + if (clip_scan == NULL) { + src_alpha = src_scan[3]; + } else { + src_alpha = clip_scan[col] * src_scan[3] / 255; } - } -} -inline void _CompositeRow_Rgb2Argb_NoBlend_NoClip(uint8_t* dest_scan, const uint8_t* src_scan, int width, int src_Bpp, - uint8_t* dest_alpha_scan) -{ - if (dest_alpha_scan == NULL) { - for (int col = 0; col < width; col ++) { - if (src_Bpp == 4) { - FXARGB_SETDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan)); - } else { - FXARGB_SETDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[2], src_scan[1], src_scan[0])); - } - dest_scan += 4; - src_scan += src_Bpp; + if (src_alpha == 0) { + dest_scan += 4; + src_scan += 4; + continue; } + uint8_t dest_alpha = + back_alpha + src_alpha - back_alpha * src_alpha / 255; + dest_scan[3] = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + if (bNonseparableBlend) { + _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); + } + for (int color = 0; color < 3; color++) { + if (blend_type) { + int blended = bNonseparableBlend + ? blended_colors[color] + : _BLEND(blend_type, *dest_scan, *src_scan); + blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); + } else { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio); + } + dest_scan++; + src_scan++; + } + dest_scan++; + src_scan++; + } } else { - int src_gap = src_Bpp - 3; - for (int col = 0; col < width; col ++) { + for (int col = 0; col < pixel_count; col++) { + uint8_t back_alpha = dest_scan[3]; + if (back_alpha == 0) { + if (clip_scan) { + int src_alpha = clip_scan[col] * (*src_alpha_scan) / 255; + FXARGB_SETDIB(dest_scan, FXARGB_MAKE((src_alpha << 24), src_scan[2], + src_scan[1], *src_scan)); + } else { + FXARGB_SETDIB(dest_scan, + FXARGB_MAKE((*src_alpha_scan << 24), src_scan[2], + src_scan[1], *src_scan)); + } + dest_scan += 4; + src_scan += 3; + src_alpha_scan++; + continue; + } + uint8_t src_alpha; + if (clip_scan == NULL) { + src_alpha = *src_alpha_scan++; + } else { + src_alpha = clip_scan[col] * (*src_alpha_scan++) / 255; + } + if (src_alpha == 0) { + dest_scan += 4; + src_scan += 3; + continue; + } + uint8_t dest_alpha = + back_alpha + src_alpha - back_alpha * src_alpha / 255; + dest_scan[3] = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + if (bNonseparableBlend) { + _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); + } + for (int color = 0; color < 3; color++) { + if (blend_type) { + int blended = bNonseparableBlend + ? blended_colors[color] + : _BLEND(blend_type, *dest_scan, *src_scan); + blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); + } else { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio); + } + dest_scan++; + src_scan++; + } + dest_scan++; + } + } + } else { + if (src_alpha_scan) { + for (int col = 0; col < pixel_count; col++) { + uint8_t back_alpha = *dest_alpha_scan; + if (back_alpha == 0) { + if (clip_scan) { + int src_alpha = clip_scan[col] * (*src_alpha_scan) / 255; + *dest_alpha_scan = src_alpha; *dest_scan++ = *src_scan++; *dest_scan++ = *src_scan++; *dest_scan++ = *src_scan++; - *dest_alpha_scan++ = 0xff; - src_scan += src_gap; + } else { + *dest_alpha_scan = *src_alpha_scan; + *dest_scan++ = *src_scan++; + *dest_scan++ = *src_scan++; + *dest_scan++ = *src_scan++; + } + dest_alpha_scan++; + src_alpha_scan++; + continue; } - } -} -inline void _CompositeRow_Argb2Rgb_Blend(uint8_t* dest_scan, const uint8_t* src_scan, int width, int blend_type, int dest_Bpp, const uint8_t* clip_scan, - const uint8_t* src_alpha_scan) -{ - int blended_colors[3]; - FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; - int dest_gap = dest_Bpp - 3; - if (src_alpha_scan == NULL) { - for (int col = 0; col < width; col ++) { - uint8_t src_alpha; - if (clip_scan) { - src_alpha = src_scan[3] * (*clip_scan++) / 255; - } else { - src_alpha = src_scan[3]; - } - if (src_alpha == 0) { - dest_scan += dest_Bpp; - src_scan += 4; - continue; - } - if (bNonseparableBlend) { - _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); - } - for (int color = 0; color < 3; color ++) { - int back_color = *dest_scan; - int blended = bNonseparableBlend ? blended_colors[color] : - _BLEND(blend_type, back_color, *src_scan); - *dest_scan = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha); - dest_scan ++; - src_scan ++; - } - dest_scan += dest_gap; - src_scan ++; + uint8_t src_alpha; + if (clip_scan == NULL) { + src_alpha = *src_alpha_scan++; + } else { + src_alpha = clip_scan[col] * (*src_alpha_scan++) / 255; } - } else { - for (int col = 0; col < width; col ++) { - uint8_t src_alpha; - if (clip_scan) { - src_alpha = (*src_alpha_scan++) * (*clip_scan++) / 255; - } else { - src_alpha = *src_alpha_scan++; - } - if (src_alpha == 0) { - dest_scan += dest_Bpp; - src_scan += 3; - continue; - } - if (bNonseparableBlend) { - _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); - } - for (int color = 0; color < 3; color ++) { - int back_color = *dest_scan; - int blended = bNonseparableBlend ? blended_colors[color] : - _BLEND(blend_type, back_color, *src_scan); - *dest_scan = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha); - dest_scan ++; - src_scan ++; - } - dest_scan += dest_gap; + if (src_alpha == 0) { + dest_scan += 3; + src_scan += 3; + dest_alpha_scan++; + continue; } - } -} -inline void _CompositeRow_Argb2Rgb_NoBlend(uint8_t* dest_scan, const uint8_t* src_scan, int width, int dest_Bpp, const uint8_t* clip_scan, - const uint8_t* src_alpha_scan) -{ - int dest_gap = dest_Bpp - 3; - if (src_alpha_scan == NULL) { - for (int col = 0; col < width; col ++) { - uint8_t src_alpha; - if (clip_scan) { - src_alpha = src_scan[3] * (*clip_scan++) / 255; - } else { - src_alpha = src_scan[3]; - } - if (src_alpha == 255) { - *dest_scan++ = *src_scan++; - *dest_scan++ = *src_scan++; - *dest_scan++ = *src_scan++; - dest_scan += dest_gap; - src_scan ++; - continue; - } - if (src_alpha == 0) { - dest_scan += dest_Bpp; - src_scan += 4; - continue; - } - for (int color = 0; color < 3; color ++) { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha); - dest_scan ++; - src_scan ++; - } - dest_scan += dest_gap; - src_scan ++; + uint8_t dest_alpha = + back_alpha + src_alpha - back_alpha * src_alpha / 255; + *dest_alpha_scan++ = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + if (bNonseparableBlend) { + _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); + } + for (int color = 0; color < 3; color++) { + if (blend_type) { + int blended = bNonseparableBlend + ? blended_colors[color] + : _BLEND(blend_type, *dest_scan, *src_scan); + blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); + } else { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio); + } + dest_scan++; + src_scan++; } + } } else { - for (int col = 0; col < width; col ++) { - uint8_t src_alpha; - if (clip_scan) { - src_alpha = (*src_alpha_scan++) * (*clip_scan++) / 255; - } else { - src_alpha = *src_alpha_scan++; - } - if (src_alpha == 255) { - *dest_scan++ = *src_scan++; - *dest_scan++ = *src_scan++; - *dest_scan++ = *src_scan++; - dest_scan += dest_gap; - continue; - } - if (src_alpha == 0) { - dest_scan += dest_Bpp; - src_scan += 3; - continue; - } - for (int color = 0; color < 3; color ++) { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha); - dest_scan ++; - src_scan ++; - } - dest_scan += dest_gap; - } - } -} -inline void _CompositeRow_Rgb2Rgb_Blend_NoClip(uint8_t* dest_scan, const uint8_t* src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp) -{ - int blended_colors[3]; - FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; - int dest_gap = dest_Bpp - 3; - int src_gap = src_Bpp - 3; - for (int col = 0; col < width; col ++) { - if (bNonseparableBlend) { - _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); + for (int col = 0; col < pixel_count; col++) { + uint8_t back_alpha = *dest_alpha_scan; + if (back_alpha == 0) { + if (clip_scan) { + int src_alpha = clip_scan[col] * src_scan[3] / 255; + *dest_alpha_scan = src_alpha; + *dest_scan++ = *src_scan++; + *dest_scan++ = *src_scan++; + *dest_scan++ = *src_scan++; + } else { + *dest_alpha_scan = src_scan[3]; + *dest_scan++ = *src_scan++; + *dest_scan++ = *src_scan++; + *dest_scan++ = *src_scan++; + } + dest_alpha_scan++; + src_scan++; + continue; } - for (int color = 0; color < 3; color ++) { - int back_color = *dest_scan; - int src_color = *src_scan; - int blended = bNonseparableBlend ? blended_colors[color] : - _BLEND(blend_type, back_color, src_color); - *dest_scan = blended; - dest_scan ++; - src_scan ++; + uint8_t src_alpha; + if (clip_scan == NULL) { + src_alpha = src_scan[3]; + } else { + src_alpha = clip_scan[col] * src_scan[3] / 255; } - dest_scan += dest_gap; - src_scan += src_gap; - } -} -inline void _CompositeRow_Rgb2Rgb_Blend_Clip(uint8_t* dest_scan, const uint8_t* src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp, const uint8_t* clip_scan) -{ - int blended_colors[3]; - FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; - int dest_gap = dest_Bpp - 3; - int src_gap = src_Bpp - 3; - for (int col = 0; col < width; col ++) { - uint8_t src_alpha = *clip_scan ++; if (src_alpha == 0) { - dest_scan += dest_Bpp; - src_scan += src_Bpp; - continue; + dest_scan += 3; + src_scan += 4; + dest_alpha_scan++; + continue; } + uint8_t dest_alpha = + back_alpha + src_alpha - back_alpha * src_alpha / 255; + *dest_alpha_scan++ = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; if (bNonseparableBlend) { - _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); + _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); + } + for (int color = 0; color < 3; color++) { + if (blend_type) { + int blended = bNonseparableBlend + ? blended_colors[color] + : _BLEND(blend_type, *dest_scan, *src_scan); + blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); + } else { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio); + } + dest_scan++; + src_scan++; } - for (int color = 0; color < 3; color ++) { - int src_color = *src_scan; - int back_color = *dest_scan; - int blended = bNonseparableBlend ? blended_colors[color] : - _BLEND(blend_type, back_color, src_color); - *dest_scan = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha); - dest_scan ++; - src_scan ++; + src_scan++; + } + } + } +} +void _CompositeRow_Rgb2Argb_Blend_NoClip(uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + int blend_type, + int src_Bpp, + uint8_t* dest_alpha_scan) { + int blended_colors[3]; + FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; + int src_gap = src_Bpp - 3; + if (dest_alpha_scan == NULL) { + for (int col = 0; col < width; col++) { + uint8_t back_alpha = dest_scan[3]; + if (back_alpha == 0) { + if (src_Bpp == 4) { + FXARGB_SETDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan)); + } else { + FXARGB_SETDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[2], src_scan[1], + src_scan[0])); } - dest_scan += dest_gap; + dest_scan += 4; + src_scan += src_Bpp; + continue; + } + dest_scan[3] = 0xff; + if (bNonseparableBlend) { + _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); + } + for (int color = 0; color < 3; color++) { + int src_color = *src_scan; + int blended = bNonseparableBlend + ? blended_colors[color] + : _BLEND(blend_type, *dest_scan, src_color); + *dest_scan = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha); + dest_scan++; + src_scan++; + } + dest_scan++; + src_scan += src_gap; + } + } else { + for (int col = 0; col < width; col++) { + uint8_t back_alpha = *dest_alpha_scan; + if (back_alpha == 0) { + *dest_scan++ = *src_scan++; + *dest_scan++ = *src_scan++; + *dest_scan++ = *src_scan++; + *dest_alpha_scan++ = 0xff; src_scan += src_gap; + continue; + } + *dest_alpha_scan++ = 0xff; + if (bNonseparableBlend) { + _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); + } + for (int color = 0; color < 3; color++) { + int src_color = *src_scan; + int blended = bNonseparableBlend + ? blended_colors[color] + : _BLEND(blend_type, *dest_scan, src_color); + *dest_scan = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha); + dest_scan++; + src_scan++; + } + src_scan += src_gap; } + } } -inline void _CompositeRow_Rgb2Rgb_NoBlend_NoClip(uint8_t* dest_scan, const uint8_t* src_scan, int width, int dest_Bpp, int src_Bpp) -{ - if (dest_Bpp == src_Bpp) { - FXSYS_memcpy(dest_scan, src_scan, width * dest_Bpp); - return; - } - for (int col = 0; col < width; col ++) { - dest_scan[0] = src_scan[0]; - dest_scan[1] = src_scan[1]; - dest_scan[2] = src_scan[2]; - dest_scan += dest_Bpp; +inline void _CompositeRow_Rgb2Argb_Blend_Clip(uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + int blend_type, + int src_Bpp, + const uint8_t* clip_scan, + uint8_t* dest_alpha_scan) { + int blended_colors[3]; + FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; + int src_gap = src_Bpp - 3; + if (dest_alpha_scan == NULL) { + for (int col = 0; col < width; col++) { + int src_alpha = *clip_scan++; + uint8_t back_alpha = dest_scan[3]; + if (back_alpha == 0) { + *dest_scan++ = *src_scan++; + *dest_scan++ = *src_scan++; + *dest_scan++ = *src_scan++; + src_scan += src_gap; + dest_scan++; + continue; + } + if (src_alpha == 0) { + dest_scan += 4; + src_scan += src_Bpp; + continue; + } + uint8_t dest_alpha = + back_alpha + src_alpha - back_alpha * src_alpha / 255; + dest_scan[3] = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + if (bNonseparableBlend) { + _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); + } + for (int color = 0; color < 3; color++) { + int src_color = *src_scan; + int blended = bNonseparableBlend + ? blended_colors[color] + : _BLEND(blend_type, *dest_scan, src_color); + blended = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); + dest_scan++; + src_scan++; + } + dest_scan++; + src_scan += src_gap; + } + } else { + for (int col = 0; col < width; col++) { + int src_alpha = *clip_scan++; + uint8_t back_alpha = *dest_alpha_scan; + if (back_alpha == 0) { + *dest_scan++ = *src_scan++; + *dest_scan++ = *src_scan++; + *dest_scan++ = *src_scan++; + src_scan += src_gap; + dest_alpha_scan++; + continue; + } + if (src_alpha == 0) { + dest_scan += 3; + dest_alpha_scan++; src_scan += src_Bpp; + continue; + } + uint8_t dest_alpha = + back_alpha + src_alpha - back_alpha * src_alpha / 255; + *dest_alpha_scan++ = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + if (bNonseparableBlend) { + _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); + } + for (int color = 0; color < 3; color++) { + int src_color = *src_scan; + int blended = bNonseparableBlend + ? blended_colors[color] + : _BLEND(blend_type, *dest_scan, src_color); + blended = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); + dest_scan++; + src_scan++; + } + src_scan += src_gap; } + } } -inline void _CompositeRow_Rgb2Rgb_NoBlend_Clip(uint8_t* dest_scan, const uint8_t* src_scan, int width, int dest_Bpp, int src_Bpp, const uint8_t* clip_scan) -{ - for (int col = 0; col < width; col ++) { - int src_alpha = clip_scan[col]; - if (src_alpha == 255) { - dest_scan[0] = src_scan[0]; - dest_scan[1] = src_scan[1]; - dest_scan[2] = src_scan[2]; - } else if (src_alpha) { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha); - dest_scan ++; - src_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha); - dest_scan ++; - src_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha); - dest_scan += dest_Bpp - 2; - src_scan += src_Bpp - 2; - continue; - } - dest_scan += dest_Bpp; +inline void _CompositeRow_Rgb2Argb_NoBlend_Clip(uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + int src_Bpp, + const uint8_t* clip_scan, + uint8_t* dest_alpha_scan) { + int src_gap = src_Bpp - 3; + if (dest_alpha_scan == NULL) { + for (int col = 0; col < width; col++) { + int src_alpha = clip_scan[col]; + if (src_alpha == 255) { + *dest_scan++ = *src_scan++; + *dest_scan++ = *src_scan++; + *dest_scan++ = *src_scan++; + *dest_scan++ = 255; + src_scan += src_gap; + continue; + } + if (src_alpha == 0) { + dest_scan += 4; + src_scan += src_Bpp; + continue; + } + int back_alpha = dest_scan[3]; + uint8_t dest_alpha = + back_alpha + src_alpha - back_alpha * src_alpha / 255; + dest_scan[3] = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + for (int color = 0; color < 3; color++) { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio); + dest_scan++; + src_scan++; + } + dest_scan++; + src_scan += src_gap; + } + } else { + for (int col = 0; col < width; col++) { + int src_alpha = clip_scan[col]; + if (src_alpha == 255) { + *dest_scan++ = *src_scan++; + *dest_scan++ = *src_scan++; + *dest_scan++ = *src_scan++; + *dest_alpha_scan++ = 255; + src_scan += src_gap; + continue; + } + if (src_alpha == 0) { + dest_scan += 3; + dest_alpha_scan++; src_scan += src_Bpp; + continue; + } + int back_alpha = *dest_alpha_scan; + uint8_t dest_alpha = + back_alpha + src_alpha - back_alpha * src_alpha / 255; + *dest_alpha_scan++ = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + for (int color = 0; color < 3; color++) { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio); + dest_scan++; + src_scan++; + } + src_scan += src_gap; } + } } -void _CompositeRow_Argb2Argb_Transform(uint8_t* dest_scan, const uint8_t* src_scan, int pixel_count, int blend_type, const uint8_t* clip_scan, - uint8_t* dest_alpha_scan, const uint8_t* src_alpha_scan, uint8_t* src_cache_scan, void* pIccTransform) -{ - uint8_t* dp = src_cache_scan; - ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - if (src_alpha_scan) { - if (dest_alpha_scan == NULL) { - for (int col = 0; col < pixel_count; col ++) { - pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1); - dp[3] = *src_alpha_scan++; - src_scan += 3; - dp += 4; - } - src_alpha_scan = NULL; - } else { - pIccModule->TranslateScanline(pIccTransform, dp, src_scan, pixel_count); - } - } else { - if (dest_alpha_scan == NULL) { - for (int col = 0; col < pixel_count; col ++) { - pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1); - dp[3] = src_scan[3]; - src_scan += 4; - dp += 4; - } - } else { - int blended_colors[3]; - FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; - for (int col = 0; col < pixel_count; col ++) { - pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, 1); - uint8_t back_alpha = *dest_alpha_scan; - if (back_alpha == 0) { - if (clip_scan) { - int src_alpha = clip_scan[col] * src_scan[3] / 255; - *dest_alpha_scan = src_alpha; - *dest_scan++ = *src_cache_scan++; - *dest_scan++ = *src_cache_scan++; - *dest_scan++ = *src_cache_scan++; - } else { - *dest_alpha_scan = src_scan[3]; - *dest_scan++ = *src_cache_scan++; - *dest_scan++ = *src_cache_scan++; - *dest_scan++ = *src_cache_scan++; - } - dest_alpha_scan ++; - src_scan += 4; - continue; - } - uint8_t src_alpha; - if (clip_scan == NULL) { - src_alpha = src_scan[3]; - } else { - src_alpha = clip_scan[col] * src_scan[3] / 255; - } - src_scan += 4; - if (src_alpha == 0) { - dest_scan += 3; - src_cache_scan += 3; - dest_alpha_scan ++; - continue; - } - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - *dest_alpha_scan ++ = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - if (bNonseparableBlend) { - _RGB_Blend(blend_type, src_cache_scan, dest_scan, blended_colors); - } - for (int color = 0; color < 3; color ++) { - if (blend_type) { - int blended = bNonseparableBlend ? blended_colors[color] : - _BLEND(blend_type, *dest_scan, *src_cache_scan); - blended = FXDIB_ALPHA_MERGE(*src_cache_scan, blended, back_alpha); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); - } else { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_cache_scan, alpha_ratio); - } - dest_scan ++; - src_cache_scan ++; - } - } - return; - } - } - _CompositeRow_Argb2Argb(dest_scan, src_cache_scan, pixel_count, blend_type, clip_scan, dest_alpha_scan, src_alpha_scan); +inline void _CompositeRow_Rgb2Argb_NoBlend_NoClip(uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + int src_Bpp, + uint8_t* dest_alpha_scan) { + if (dest_alpha_scan == NULL) { + for (int col = 0; col < width; col++) { + if (src_Bpp == 4) { + FXARGB_SETDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan)); + } else { + FXARGB_SETDIB(dest_scan, + FXARGB_MAKE(0xff, src_scan[2], src_scan[1], src_scan[0])); + } + dest_scan += 4; + src_scan += src_Bpp; + } + } else { + int src_gap = src_Bpp - 3; + for (int col = 0; col < width; col++) { + *dest_scan++ = *src_scan++; + *dest_scan++ = *src_scan++; + *dest_scan++ = *src_scan++; + *dest_alpha_scan++ = 0xff; + src_scan += src_gap; + } + } } -void _CompositeRow_Rgb2Argb_Blend_NoClip_Transform(uint8_t* dest_scan, const uint8_t* src_scan, int width, int blend_type, int src_Bpp, - uint8_t* dest_alpha_scan, uint8_t* src_cache_scan, void* pIccTransform) -{ - ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - if (src_Bpp == 3) { - pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width); - } else { - uint8_t* dp = src_cache_scan; - for (int col = 0; col < width; col ++) { - pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1); - src_scan += 4; - dp += 3; - } +inline void _CompositeRow_Argb2Rgb_Blend(uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + int blend_type, + int dest_Bpp, + const uint8_t* clip_scan, + const uint8_t* src_alpha_scan) { + int blended_colors[3]; + FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; + int dest_gap = dest_Bpp - 3; + if (src_alpha_scan == NULL) { + for (int col = 0; col < width; col++) { + uint8_t src_alpha; + if (clip_scan) { + src_alpha = src_scan[3] * (*clip_scan++) / 255; + } else { + src_alpha = src_scan[3]; + } + if (src_alpha == 0) { + dest_scan += dest_Bpp; + src_scan += 4; + continue; + } + if (bNonseparableBlend) { + _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); + } + for (int color = 0; color < 3; color++) { + int back_color = *dest_scan; + int blended = bNonseparableBlend + ? blended_colors[color] + : _BLEND(blend_type, back_color, *src_scan); + *dest_scan = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha); + dest_scan++; + src_scan++; + } + dest_scan += dest_gap; + src_scan++; + } + } else { + for (int col = 0; col < width; col++) { + uint8_t src_alpha; + if (clip_scan) { + src_alpha = (*src_alpha_scan++) * (*clip_scan++) / 255; + } else { + src_alpha = *src_alpha_scan++; + } + if (src_alpha == 0) { + dest_scan += dest_Bpp; + src_scan += 3; + continue; + } + if (bNonseparableBlend) { + _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); + } + for (int color = 0; color < 3; color++) { + int back_color = *dest_scan; + int blended = bNonseparableBlend + ? blended_colors[color] + : _BLEND(blend_type, back_color, *src_scan); + *dest_scan = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha); + dest_scan++; + src_scan++; + } + dest_scan += dest_gap; } - _CompositeRow_Rgb2Argb_Blend_NoClip(dest_scan, src_cache_scan, width, blend_type, 3, dest_alpha_scan); + } } -inline void _CompositeRow_Rgb2Argb_Blend_Clip_Transform(uint8_t* dest_scan, const uint8_t* src_scan, int width, int blend_type, int src_Bpp, const uint8_t* clip_scan, - uint8_t* dest_alpha_scan, uint8_t* src_cache_scan, void* pIccTransform) -{ - ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - if (src_Bpp == 3) { - pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width); - } else { - uint8_t* dp = src_cache_scan; - for (int col = 0; col < width; col ++) { - pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1); - src_scan += 4; - dp += 3; - } +inline void _CompositeRow_Argb2Rgb_NoBlend(uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + int dest_Bpp, + const uint8_t* clip_scan, + const uint8_t* src_alpha_scan) { + int dest_gap = dest_Bpp - 3; + if (src_alpha_scan == NULL) { + for (int col = 0; col < width; col++) { + uint8_t src_alpha; + if (clip_scan) { + src_alpha = src_scan[3] * (*clip_scan++) / 255; + } else { + src_alpha = src_scan[3]; + } + if (src_alpha == 255) { + *dest_scan++ = *src_scan++; + *dest_scan++ = *src_scan++; + *dest_scan++ = *src_scan++; + dest_scan += dest_gap; + src_scan++; + continue; + } + if (src_alpha == 0) { + dest_scan += dest_Bpp; + src_scan += 4; + continue; + } + for (int color = 0; color < 3; color++) { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha); + dest_scan++; + src_scan++; + } + dest_scan += dest_gap; + src_scan++; + } + } else { + for (int col = 0; col < width; col++) { + uint8_t src_alpha; + if (clip_scan) { + src_alpha = (*src_alpha_scan++) * (*clip_scan++) / 255; + } else { + src_alpha = *src_alpha_scan++; + } + if (src_alpha == 255) { + *dest_scan++ = *src_scan++; + *dest_scan++ = *src_scan++; + *dest_scan++ = *src_scan++; + dest_scan += dest_gap; + continue; + } + if (src_alpha == 0) { + dest_scan += dest_Bpp; + src_scan += 3; + continue; + } + for (int color = 0; color < 3; color++) { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha); + dest_scan++; + src_scan++; + } + dest_scan += dest_gap; } - _CompositeRow_Rgb2Argb_Blend_Clip(dest_scan, src_cache_scan, width, blend_type, 3, clip_scan, dest_alpha_scan); + } } -inline void _CompositeRow_Rgb2Argb_NoBlend_Clip_Transform(uint8_t* dest_scan, const uint8_t* src_scan, int width, int src_Bpp, const uint8_t* clip_scan, - uint8_t* dest_alpha_scan, uint8_t* src_cache_scan, void* pIccTransform) -{ - ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - if (src_Bpp == 3) { - pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width); - } else { - uint8_t* dp = src_cache_scan; - for (int col = 0; col < width; col ++) { - pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1); - src_scan += 4; - dp += 3; - } - } - _CompositeRow_Rgb2Argb_NoBlend_Clip(dest_scan, src_cache_scan, width, 3, clip_scan, dest_alpha_scan); +inline void _CompositeRow_Rgb2Rgb_Blend_NoClip(uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + int blend_type, + int dest_Bpp, + int src_Bpp) { + int blended_colors[3]; + FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; + int dest_gap = dest_Bpp - 3; + int src_gap = src_Bpp - 3; + for (int col = 0; col < width; col++) { + if (bNonseparableBlend) { + _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); + } + for (int color = 0; color < 3; color++) { + int back_color = *dest_scan; + int src_color = *src_scan; + int blended = bNonseparableBlend + ? blended_colors[color] + : _BLEND(blend_type, back_color, src_color); + *dest_scan = blended; + dest_scan++; + src_scan++; + } + dest_scan += dest_gap; + src_scan += src_gap; + } } -inline void _CompositeRow_Rgb2Argb_NoBlend_NoClip_Transform(uint8_t* dest_scan, const uint8_t* src_scan, int width, int src_Bpp, - uint8_t* dest_alpha_scan, uint8_t* src_cache_scan, void* pIccTransform) -{ - ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - if (src_Bpp == 3) { - pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width); - } else { - uint8_t* dp = src_cache_scan; - for (int col = 0; col < width; col ++) { - pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1); - src_scan += 4; - dp += 3; - } - } - _CompositeRow_Rgb2Argb_NoBlend_NoClip(dest_scan, src_cache_scan, width, 3, dest_alpha_scan); +inline void _CompositeRow_Rgb2Rgb_Blend_Clip(uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + int blend_type, + int dest_Bpp, + int src_Bpp, + const uint8_t* clip_scan) { + int blended_colors[3]; + FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; + int dest_gap = dest_Bpp - 3; + int src_gap = src_Bpp - 3; + for (int col = 0; col < width; col++) { + uint8_t src_alpha = *clip_scan++; + if (src_alpha == 0) { + dest_scan += dest_Bpp; + src_scan += src_Bpp; + continue; + } + if (bNonseparableBlend) { + _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); + } + for (int color = 0; color < 3; color++) { + int src_color = *src_scan; + int back_color = *dest_scan; + int blended = bNonseparableBlend + ? blended_colors[color] + : _BLEND(blend_type, back_color, src_color); + *dest_scan = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha); + dest_scan++; + src_scan++; + } + dest_scan += dest_gap; + src_scan += src_gap; + } } -inline void _CompositeRow_Argb2Rgb_Blend_Transform(uint8_t* dest_scan, const uint8_t* src_scan, int width, int blend_type, int dest_Bpp, const uint8_t* clip_scan, - const uint8_t* src_alpha_scan, uint8_t* src_cache_scan, void* pIccTransform) -{ - ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - if (src_alpha_scan) { - pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width); - } else { - int blended_colors[3]; - FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; - int dest_gap = dest_Bpp - 3; - for (int col = 0; col < width; col ++) { - pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, 1); - uint8_t src_alpha; - if (clip_scan) { - src_alpha = src_scan[3] * (*clip_scan++) / 255; - } else { - src_alpha = src_scan[3]; - } - src_scan += 4; - if (src_alpha == 0) { - dest_scan += dest_Bpp; - src_cache_scan += 3; - continue; - } - if (bNonseparableBlend) { - _RGB_Blend(blend_type, src_cache_scan, dest_scan, blended_colors); - } - for (int color = 0; color < 3; color ++) { - int back_color = *dest_scan; - int blended = bNonseparableBlend ? blended_colors[color] : - _BLEND(blend_type, back_color, *src_cache_scan); - *dest_scan = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha); - dest_scan ++; - src_cache_scan ++; - } - dest_scan += dest_gap; - } - return; - } - _CompositeRow_Argb2Rgb_Blend(dest_scan, src_cache_scan, width, blend_type, dest_Bpp, clip_scan, src_alpha_scan); +inline void _CompositeRow_Rgb2Rgb_NoBlend_NoClip(uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + int dest_Bpp, + int src_Bpp) { + if (dest_Bpp == src_Bpp) { + FXSYS_memcpy(dest_scan, src_scan, width * dest_Bpp); + return; + } + for (int col = 0; col < width; col++) { + dest_scan[0] = src_scan[0]; + dest_scan[1] = src_scan[1]; + dest_scan[2] = src_scan[2]; + dest_scan += dest_Bpp; + src_scan += src_Bpp; + } } -inline void _CompositeRow_Argb2Rgb_NoBlend_Transform(uint8_t* dest_scan, const uint8_t* src_scan, int width, int dest_Bpp, const uint8_t* clip_scan, - const uint8_t* src_alpha_scan, uint8_t* src_cache_scan, void* pIccTransform) -{ - ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - if (src_alpha_scan) { - pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width); - } else { - int dest_gap = dest_Bpp - 3; - for (int col = 0; col < width; col ++) { - pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, 1); - uint8_t src_alpha; - if (clip_scan) { - src_alpha = src_scan[3] * (*clip_scan++) / 255; - } else { - src_alpha = src_scan[3]; - } - src_scan += 4; - if (src_alpha == 255) { - *dest_scan++ = *src_cache_scan++; - *dest_scan++ = *src_cache_scan++; - *dest_scan++ = *src_cache_scan++; - dest_scan += dest_gap; - continue; - } - if (src_alpha == 0) { - dest_scan += dest_Bpp; - src_cache_scan += 3; - continue; - } - for (int color = 0; color < 3; color ++) { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_cache_scan, src_alpha); - dest_scan ++; - src_cache_scan ++; - } - dest_scan += dest_gap; - } - return; - } - _CompositeRow_Argb2Rgb_NoBlend(dest_scan, src_cache_scan, width, dest_Bpp, clip_scan, src_alpha_scan); +inline void _CompositeRow_Rgb2Rgb_NoBlend_Clip(uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + int dest_Bpp, + int src_Bpp, + const uint8_t* clip_scan) { + for (int col = 0; col < width; col++) { + int src_alpha = clip_scan[col]; + if (src_alpha == 255) { + dest_scan[0] = src_scan[0]; + dest_scan[1] = src_scan[1]; + dest_scan[2] = src_scan[2]; + } else if (src_alpha) { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha); + dest_scan++; + src_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha); + dest_scan++; + src_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha); + dest_scan += dest_Bpp - 2; + src_scan += src_Bpp - 2; + continue; + } + dest_scan += dest_Bpp; + src_scan += src_Bpp; + } } -inline void _CompositeRow_Rgb2Rgb_Blend_NoClip_Transform(uint8_t* dest_scan, const uint8_t* src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp, - uint8_t* src_cache_scan, void* pIccTransform) -{ - ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - if (src_Bpp == 3) { - pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width); +void _CompositeRow_Argb2Argb_Transform(uint8_t* dest_scan, + const uint8_t* src_scan, + int pixel_count, + int blend_type, + const uint8_t* clip_scan, + uint8_t* dest_alpha_scan, + const uint8_t* src_alpha_scan, + uint8_t* src_cache_scan, + void* pIccTransform) { + uint8_t* dp = src_cache_scan; + ICodec_IccModule* pIccModule = + CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + if (src_alpha_scan) { + if (dest_alpha_scan == NULL) { + for (int col = 0; col < pixel_count; col++) { + pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1); + dp[3] = *src_alpha_scan++; + src_scan += 3; + dp += 4; + } + src_alpha_scan = NULL; } else { - uint8_t* dp = src_cache_scan; - for (int col = 0; col < width; col ++) { - pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1); - src_scan += 4; - dp += 3; - } + pIccModule->TranslateScanline(pIccTransform, dp, src_scan, pixel_count); } - _CompositeRow_Rgb2Rgb_Blend_NoClip(dest_scan, src_cache_scan, width, blend_type, dest_Bpp, 3); -} -inline void _CompositeRow_Rgb2Rgb_Blend_Clip_Transform(uint8_t* dest_scan, const uint8_t* src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp, const uint8_t* clip_scan, - uint8_t* src_cache_scan, void* pIccTransform) -{ - ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - if (src_Bpp == 3) { - pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width); + } else { + if (dest_alpha_scan == NULL) { + for (int col = 0; col < pixel_count; col++) { + pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1); + dp[3] = src_scan[3]; + src_scan += 4; + dp += 4; + } } else { - uint8_t* dp = src_cache_scan; - for (int col = 0; col < width; col ++) { - pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1); - src_scan += 4; - dp += 3; + int blended_colors[3]; + FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; + for (int col = 0; col < pixel_count; col++) { + pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, + 1); + uint8_t back_alpha = *dest_alpha_scan; + if (back_alpha == 0) { + if (clip_scan) { + int src_alpha = clip_scan[col] * src_scan[3] / 255; + *dest_alpha_scan = src_alpha; + *dest_scan++ = *src_cache_scan++; + *dest_scan++ = *src_cache_scan++; + *dest_scan++ = *src_cache_scan++; + } else { + *dest_alpha_scan = src_scan[3]; + *dest_scan++ = *src_cache_scan++; + *dest_scan++ = *src_cache_scan++; + *dest_scan++ = *src_cache_scan++; + } + dest_alpha_scan++; + src_scan += 4; + continue; } - } - _CompositeRow_Rgb2Rgb_Blend_Clip(dest_scan, src_cache_scan, width, blend_type, dest_Bpp, 3, clip_scan); -} -inline void _CompositeRow_Rgb2Rgb_NoBlend_NoClip_Transform(uint8_t* dest_scan, const uint8_t* src_scan, int width, int dest_Bpp, int src_Bpp, - uint8_t* src_cache_scan, void* pIccTransform) -{ - ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - if (src_Bpp == 3) { - pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width); - } else { - uint8_t* dp = src_cache_scan; - for (int col = 0; col < width; col ++) { - pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1); - src_scan += 4; - dp += 3; + uint8_t src_alpha; + if (clip_scan == NULL) { + src_alpha = src_scan[3]; + } else { + src_alpha = clip_scan[col] * src_scan[3] / 255; } - } - _CompositeRow_Rgb2Rgb_NoBlend_NoClip(dest_scan, src_cache_scan, width, dest_Bpp, 3); -} -inline void _CompositeRow_Rgb2Rgb_NoBlend_Clip_Transform(uint8_t* dest_scan, const uint8_t* src_scan, int width, int dest_Bpp, int src_Bpp, const uint8_t* clip_scan, - uint8_t* src_cache_scan, void* pIccTransform) -{ - ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - if (src_Bpp == 3) { - pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width); - } else { - uint8_t* dp = src_cache_scan; - for (int col = 0; col < width; col ++) { - pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1); - src_scan += 4; - dp += 3; + src_scan += 4; + if (src_alpha == 0) { + dest_scan += 3; + src_cache_scan += 3; + dest_alpha_scan++; + continue; } - } - _CompositeRow_Rgb2Rgb_NoBlend_Clip(dest_scan, src_cache_scan, width, dest_Bpp, 3, clip_scan); + uint8_t dest_alpha = + back_alpha + src_alpha - back_alpha * src_alpha / 255; + *dest_alpha_scan++ = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + if (bNonseparableBlend) { + _RGB_Blend(blend_type, src_cache_scan, dest_scan, blended_colors); + } + for (int color = 0; color < 3; color++) { + if (blend_type) { + int blended = bNonseparableBlend + ? blended_colors[color] + : _BLEND(blend_type, *dest_scan, *src_cache_scan); + blended = FXDIB_ALPHA_MERGE(*src_cache_scan, blended, back_alpha); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); + } else { + *dest_scan = + FXDIB_ALPHA_MERGE(*dest_scan, *src_cache_scan, alpha_ratio); + } + dest_scan++; + src_cache_scan++; + } + } + return; + } + } + _CompositeRow_Argb2Argb(dest_scan, src_cache_scan, pixel_count, blend_type, + clip_scan, dest_alpha_scan, src_alpha_scan); } -inline void _CompositeRow_8bppPal2Gray(uint8_t* dest_scan, const uint8_t* src_scan, const uint8_t* pPalette, int pixel_count, - int blend_type, const uint8_t* clip_scan, - const uint8_t* src_alpha_scan) -{ - if (src_alpha_scan) { - if (blend_type) { - FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; - int blended_color; - for (int col = 0; col < pixel_count; col ++) { - uint8_t gray = pPalette[*src_scan]; - int src_alpha = *src_alpha_scan++; - if (clip_scan) { - src_alpha = clip_scan[col] * src_alpha / 255; - } - if (bNonseparableBlend) { - blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan; - } - gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray); - if (src_alpha) { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha); - } else { - *dest_scan = gray; - } - dest_scan ++; - src_scan ++; - } - return; - } - for (int col = 0; col < pixel_count; col ++) { - uint8_t gray = pPalette[*src_scan]; - int src_alpha = *src_alpha_scan++; - if (clip_scan) { - src_alpha = clip_scan[col] * src_alpha / 255; - } - if (src_alpha) { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha); - } else { - *dest_scan = gray; - } - dest_scan ++; - src_scan ++; - } - } else { - if (blend_type) { - FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; - int blended_color; - for (int col = 0; col < pixel_count; col ++) { - uint8_t gray = pPalette[*src_scan]; - if (bNonseparableBlend) { - blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan; - } - gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray); - if (clip_scan && clip_scan[col] < 255) { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]); - } else { - *dest_scan = gray; - } - dest_scan ++; - src_scan ++; - } - return; - } - for (int col = 0; col < pixel_count; col ++) { - uint8_t gray = pPalette[*src_scan]; - if (clip_scan && clip_scan[col] < 255) { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]); - } else { - *dest_scan = gray; - } - dest_scan ++; - src_scan ++; - } - } +void _CompositeRow_Rgb2Argb_Blend_NoClip_Transform(uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + int blend_type, + int src_Bpp, + uint8_t* dest_alpha_scan, + uint8_t* src_cache_scan, + void* pIccTransform) { + ICodec_IccModule* pIccModule = + CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + if (src_Bpp == 3) { + pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, + width); + } else { + uint8_t* dp = src_cache_scan; + for (int col = 0; col < width; col++) { + pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1); + src_scan += 4; + dp += 3; + } + } + _CompositeRow_Rgb2Argb_Blend_NoClip(dest_scan, src_cache_scan, width, + blend_type, 3, dest_alpha_scan); } -inline void _CompositeRow_8bppPal2Graya(uint8_t* dest_scan, const uint8_t* src_scan, const uint8_t* pPalette, int pixel_count, - int blend_type, const uint8_t* clip_scan, - uint8_t* dest_alpha_scan, const uint8_t* src_alpha_scan) -{ - if (src_alpha_scan) { - if (blend_type) { - FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; - int blended_color; - for (int col = 0; col < pixel_count; col ++) { - uint8_t gray = pPalette[*src_scan]; - src_scan ++; - uint8_t back_alpha = *dest_alpha_scan; - if (back_alpha == 0) { - int src_alpha = *src_alpha_scan ++; - if (clip_scan) { - src_alpha = clip_scan[col] * src_alpha / 255; - } - if (src_alpha) { - *dest_scan = gray; - *dest_alpha_scan = src_alpha; - } - dest_scan ++; - dest_alpha_scan ++; - continue; - } - uint8_t src_alpha = *src_alpha_scan++; - if (clip_scan) { - src_alpha = clip_scan[col] * src_alpha / 255; - } - if (src_alpha == 0) { - dest_scan ++; - dest_alpha_scan ++; - continue; - } - *dest_alpha_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255; - int alpha_ratio = src_alpha * 255 / (*dest_alpha_scan); - if (bNonseparableBlend) { - blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan; - } - gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio); - dest_alpha_scan ++; - dest_scan ++; - } - return; - } - for (int col = 0; col < pixel_count; col ++) { - uint8_t gray = pPalette[*src_scan]; - src_scan ++; - uint8_t back_alpha = *dest_alpha_scan; - if (back_alpha == 0) { - int src_alpha = *src_alpha_scan ++; - if (clip_scan) { - src_alpha = clip_scan[col] * src_alpha / 255; - } - if (src_alpha) { - *dest_scan = gray; - *dest_alpha_scan = src_alpha; - } - dest_scan ++; - dest_alpha_scan ++; - continue; - } - uint8_t src_alpha = *src_alpha_scan++; - if (clip_scan) { - src_alpha = clip_scan[col] * src_alpha / 255; - } - if (src_alpha == 0) { - dest_scan ++; - dest_alpha_scan ++; - continue; - } - *dest_alpha_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255; - int alpha_ratio = src_alpha * 255 / (*dest_alpha_scan); - dest_alpha_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio); - dest_scan ++; +inline void _CompositeRow_Rgb2Argb_Blend_Clip_Transform( + uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + int blend_type, + int src_Bpp, + const uint8_t* clip_scan, + uint8_t* dest_alpha_scan, + uint8_t* src_cache_scan, + void* pIccTransform) { + ICodec_IccModule* pIccModule = + CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + if (src_Bpp == 3) { + pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, + width); + } else { + uint8_t* dp = src_cache_scan; + for (int col = 0; col < width; col++) { + pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1); + src_scan += 4; + dp += 3; + } + } + _CompositeRow_Rgb2Argb_Blend_Clip(dest_scan, src_cache_scan, width, + blend_type, 3, clip_scan, dest_alpha_scan); +} +inline void _CompositeRow_Rgb2Argb_NoBlend_Clip_Transform( + uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + int src_Bpp, + const uint8_t* clip_scan, + uint8_t* dest_alpha_scan, + uint8_t* src_cache_scan, + void* pIccTransform) { + ICodec_IccModule* pIccModule = + CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + if (src_Bpp == 3) { + pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, + width); + } else { + uint8_t* dp = src_cache_scan; + for (int col = 0; col < width; col++) { + pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1); + src_scan += 4; + dp += 3; + } + } + _CompositeRow_Rgb2Argb_NoBlend_Clip(dest_scan, src_cache_scan, width, 3, + clip_scan, dest_alpha_scan); +} +inline void _CompositeRow_Rgb2Argb_NoBlend_NoClip_Transform( + uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + int src_Bpp, + uint8_t* dest_alpha_scan, + uint8_t* src_cache_scan, + void* pIccTransform) { + ICodec_IccModule* pIccModule = + CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + if (src_Bpp == 3) { + pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, + width); + } else { + uint8_t* dp = src_cache_scan; + for (int col = 0; col < width; col++) { + pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1); + src_scan += 4; + dp += 3; + } + } + _CompositeRow_Rgb2Argb_NoBlend_NoClip(dest_scan, src_cache_scan, width, 3, + dest_alpha_scan); +} +inline void _CompositeRow_Argb2Rgb_Blend_Transform( + uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + int blend_type, + int dest_Bpp, + const uint8_t* clip_scan, + const uint8_t* src_alpha_scan, + uint8_t* src_cache_scan, + void* pIccTransform) { + ICodec_IccModule* pIccModule = + CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + if (src_alpha_scan) { + pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, + width); + } else { + int blended_colors[3]; + FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; + int dest_gap = dest_Bpp - 3; + for (int col = 0; col < width; col++) { + pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, 1); + uint8_t src_alpha; + if (clip_scan) { + src_alpha = src_scan[3] * (*clip_scan++) / 255; + } else { + src_alpha = src_scan[3]; + } + src_scan += 4; + if (src_alpha == 0) { + dest_scan += dest_Bpp; + src_cache_scan += 3; + continue; + } + if (bNonseparableBlend) { + _RGB_Blend(blend_type, src_cache_scan, dest_scan, blended_colors); + } + for (int color = 0; color < 3; color++) { + int back_color = *dest_scan; + int blended = bNonseparableBlend + ? blended_colors[color] + : _BLEND(blend_type, back_color, *src_cache_scan); + *dest_scan = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha); + dest_scan++; + src_cache_scan++; + } + dest_scan += dest_gap; + } + return; + } + _CompositeRow_Argb2Rgb_Blend(dest_scan, src_cache_scan, width, blend_type, + dest_Bpp, clip_scan, src_alpha_scan); +} +inline void _CompositeRow_Argb2Rgb_NoBlend_Transform( + uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + int dest_Bpp, + const uint8_t* clip_scan, + const uint8_t* src_alpha_scan, + uint8_t* src_cache_scan, + void* pIccTransform) { + ICodec_IccModule* pIccModule = + CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + if (src_alpha_scan) { + pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, + width); + } else { + int dest_gap = dest_Bpp - 3; + for (int col = 0; col < width; col++) { + pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, 1); + uint8_t src_alpha; + if (clip_scan) { + src_alpha = src_scan[3] * (*clip_scan++) / 255; + } else { + src_alpha = src_scan[3]; + } + src_scan += 4; + if (src_alpha == 255) { + *dest_scan++ = *src_cache_scan++; + *dest_scan++ = *src_cache_scan++; + *dest_scan++ = *src_cache_scan++; + dest_scan += dest_gap; + continue; + } + if (src_alpha == 0) { + dest_scan += dest_Bpp; + src_cache_scan += 3; + continue; + } + for (int color = 0; color < 3; color++) { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_cache_scan, src_alpha); + dest_scan++; + src_cache_scan++; + } + dest_scan += dest_gap; + } + return; + } + _CompositeRow_Argb2Rgb_NoBlend(dest_scan, src_cache_scan, width, dest_Bpp, + clip_scan, src_alpha_scan); +} +inline void _CompositeRow_Rgb2Rgb_Blend_NoClip_Transform( + uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + int blend_type, + int dest_Bpp, + int src_Bpp, + uint8_t* src_cache_scan, + void* pIccTransform) { + ICodec_IccModule* pIccModule = + CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + if (src_Bpp == 3) { + pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, + width); + } else { + uint8_t* dp = src_cache_scan; + for (int col = 0; col < width; col++) { + pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1); + src_scan += 4; + dp += 3; + } + } + _CompositeRow_Rgb2Rgb_Blend_NoClip(dest_scan, src_cache_scan, width, + blend_type, dest_Bpp, 3); +} +inline void _CompositeRow_Rgb2Rgb_Blend_Clip_Transform(uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + int blend_type, + int dest_Bpp, + int src_Bpp, + const uint8_t* clip_scan, + uint8_t* src_cache_scan, + void* pIccTransform) { + ICodec_IccModule* pIccModule = + CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + if (src_Bpp == 3) { + pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, + width); + } else { + uint8_t* dp = src_cache_scan; + for (int col = 0; col < width; col++) { + pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1); + src_scan += 4; + dp += 3; + } + } + _CompositeRow_Rgb2Rgb_Blend_Clip(dest_scan, src_cache_scan, width, blend_type, + dest_Bpp, 3, clip_scan); +} +inline void _CompositeRow_Rgb2Rgb_NoBlend_NoClip_Transform( + uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + int dest_Bpp, + int src_Bpp, + uint8_t* src_cache_scan, + void* pIccTransform) { + ICodec_IccModule* pIccModule = + CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + if (src_Bpp == 3) { + pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, + width); + } else { + uint8_t* dp = src_cache_scan; + for (int col = 0; col < width; col++) { + pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1); + src_scan += 4; + dp += 3; + } + } + _CompositeRow_Rgb2Rgb_NoBlend_NoClip(dest_scan, src_cache_scan, width, + dest_Bpp, 3); +} +inline void _CompositeRow_Rgb2Rgb_NoBlend_Clip_Transform( + uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + int dest_Bpp, + int src_Bpp, + const uint8_t* clip_scan, + uint8_t* src_cache_scan, + void* pIccTransform) { + ICodec_IccModule* pIccModule = + CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + if (src_Bpp == 3) { + pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, + width); + } else { + uint8_t* dp = src_cache_scan; + for (int col = 0; col < width; col++) { + pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1); + src_scan += 4; + dp += 3; + } + } + _CompositeRow_Rgb2Rgb_NoBlend_Clip(dest_scan, src_cache_scan, width, dest_Bpp, + 3, clip_scan); +} +inline void _CompositeRow_8bppPal2Gray(uint8_t* dest_scan, + const uint8_t* src_scan, + const uint8_t* pPalette, + int pixel_count, + int blend_type, + const uint8_t* clip_scan, + const uint8_t* src_alpha_scan) { + if (src_alpha_scan) { + if (blend_type) { + FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; + int blended_color; + for (int col = 0; col < pixel_count; col++) { + uint8_t gray = pPalette[*src_scan]; + int src_alpha = *src_alpha_scan++; + if (clip_scan) { + src_alpha = clip_scan[col] * src_alpha / 255; } - } else { - if (blend_type) { - FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; - int blended_color; - for (int col = 0; col < pixel_count; col ++) { - uint8_t gray = pPalette[*src_scan]; - src_scan ++; - if (clip_scan == NULL || clip_scan[col] == 255) { - *dest_scan++ = gray; - *dest_alpha_scan++ = 255; - continue; - } - int src_alpha = clip_scan[col]; - if (src_alpha == 0) { - dest_scan ++; - dest_alpha_scan ++; - continue; - } - int back_alpha = *dest_alpha_scan; - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - *dest_alpha_scan ++ = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - if (bNonseparableBlend) { - blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan; - } - gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio); - dest_scan ++; - } - return; + if (bNonseparableBlend) { + blended_color = + blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan; } - for (int col = 0; col < pixel_count; col ++) { - uint8_t gray = pPalette[*src_scan]; - src_scan ++; - if (clip_scan == NULL || clip_scan[col] == 255) { - *dest_scan++ = gray; - *dest_alpha_scan++ = 255; - continue; - } - int src_alpha = clip_scan[col]; - if (src_alpha == 0) { - dest_scan ++; - dest_alpha_scan ++; - continue; - } - int back_alpha = *dest_alpha_scan; - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - *dest_alpha_scan ++ = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio); - dest_scan ++; + gray = bNonseparableBlend ? blended_color + : _BLEND(blend_type, *dest_scan, gray); + if (src_alpha) { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha); + } else { + *dest_scan = gray; } - } -} -inline void _CompositeRow_1bppPal2Gray(uint8_t* dest_scan, const uint8_t* src_scan, int src_left, - const uint8_t* pPalette, int pixel_count, int blend_type, const uint8_t* clip_scan) -{ - int reset_gray = pPalette[0]; - int set_gray = pPalette[1]; + dest_scan++; + src_scan++; + } + return; + } + for (int col = 0; col < pixel_count; col++) { + uint8_t gray = pPalette[*src_scan]; + int src_alpha = *src_alpha_scan++; + if (clip_scan) { + src_alpha = clip_scan[col] * src_alpha / 255; + } + if (src_alpha) { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha); + } else { + *dest_scan = gray; + } + dest_scan++; + src_scan++; + } + } else { if (blend_type) { - FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; - int blended_color; - for (int col = 0; col < pixel_count; col ++) { - uint8_t gray = (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) ? set_gray : reset_gray; - if (bNonseparableBlend) { - blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan; - } - gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray); - if (clip_scan && clip_scan[col] < 255) { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]); - } else { - *dest_scan = gray; - } - dest_scan ++; + FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; + int blended_color; + for (int col = 0; col < pixel_count; col++) { + uint8_t gray = pPalette[*src_scan]; + if (bNonseparableBlend) { + blended_color = + blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan; } - return; - } - for (int col = 0; col < pixel_count; col ++) { - uint8_t gray = (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) ? set_gray : reset_gray; + gray = bNonseparableBlend ? blended_color + : _BLEND(blend_type, *dest_scan, gray); if (clip_scan && clip_scan[col] < 255) { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]); } else { - *dest_scan = gray; + *dest_scan = gray; } - dest_scan ++; - } + dest_scan++; + src_scan++; + } + return; + } + for (int col = 0; col < pixel_count; col++) { + uint8_t gray = pPalette[*src_scan]; + if (clip_scan && clip_scan[col] < 255) { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]); + } else { + *dest_scan = gray; + } + dest_scan++; + src_scan++; + } + } } -inline void _CompositeRow_1bppPal2Graya(uint8_t* dest_scan, const uint8_t* src_scan, int src_left, - const uint8_t* pPalette, int pixel_count, int blend_type, const uint8_t* clip_scan, - uint8_t* dest_alpha_scan) -{ - int reset_gray = pPalette[0]; - int set_gray = pPalette[1]; +inline void _CompositeRow_8bppPal2Graya(uint8_t* dest_scan, + const uint8_t* src_scan, + const uint8_t* pPalette, + int pixel_count, + int blend_type, + const uint8_t* clip_scan, + uint8_t* dest_alpha_scan, + const uint8_t* src_alpha_scan) { + if (src_alpha_scan) { if (blend_type) { - FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; - int blended_color; - for (int col = 0; col < pixel_count; col ++) { - uint8_t gray = (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) ? set_gray : reset_gray; - if (clip_scan == NULL || clip_scan[col] == 255) { - *dest_scan++ = gray; - *dest_alpha_scan ++ = 255; - continue; - } - int src_alpha = clip_scan[col]; - if (src_alpha == 0) { - dest_scan ++; - dest_alpha_scan ++; - continue; - } - int back_alpha = *dest_alpha_scan; - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - *dest_alpha_scan ++ = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - if (bNonseparableBlend) { - blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan; - } - gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio); - dest_scan ++; + FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; + int blended_color; + for (int col = 0; col < pixel_count; col++) { + uint8_t gray = pPalette[*src_scan]; + src_scan++; + uint8_t back_alpha = *dest_alpha_scan; + if (back_alpha == 0) { + int src_alpha = *src_alpha_scan++; + if (clip_scan) { + src_alpha = clip_scan[col] * src_alpha / 255; + } + if (src_alpha) { + *dest_scan = gray; + *dest_alpha_scan = src_alpha; + } + dest_scan++; + dest_alpha_scan++; + continue; } - return; - } - for (int col = 0; col < pixel_count; col ++) { - uint8_t gray = (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) ? set_gray : reset_gray; - if (clip_scan == NULL || clip_scan[col] == 255) { - *dest_scan++ = gray; - *dest_alpha_scan ++ = 255; - continue; + uint8_t src_alpha = *src_alpha_scan++; + if (clip_scan) { + src_alpha = clip_scan[col] * src_alpha / 255; } - int src_alpha = clip_scan[col]; if (src_alpha == 0) { - dest_scan ++; - dest_alpha_scan ++; - continue; + dest_scan++; + dest_alpha_scan++; + continue; } - int back_alpha = *dest_alpha_scan; - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - *dest_alpha_scan ++ = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio); - dest_scan ++; - } -} -inline void _CompositeRow_8bppRgb2Rgb_NoBlend(uint8_t* dest_scan, const uint8_t* src_scan, FX_DWORD* pPalette, int pixel_count, - int DestBpp, const uint8_t* clip_scan, - const uint8_t* src_alpha_scan) -{ - if (src_alpha_scan) { - int dest_gap = DestBpp - 3; - FX_ARGB argb = 0; - for (int col = 0; col < pixel_count; col ++) { - argb = pPalette[*src_scan]; - int src_r = FXARGB_R(argb); - int src_g = FXARGB_G(argb); - int src_b = FXARGB_B(argb); - src_scan ++; - uint8_t src_alpha = 0; - if (clip_scan) { - src_alpha = (*src_alpha_scan++) * (*clip_scan++) / 255; - } else { - src_alpha = *src_alpha_scan++; - } - if (src_alpha == 255) { - *dest_scan++ = src_b; - *dest_scan++ = src_g; - *dest_scan++ = src_r; - dest_scan += dest_gap; - continue; - } - if (src_alpha == 0) { - dest_scan += DestBpp; - continue; - } - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, src_alpha); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, src_alpha); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, src_alpha); - dest_scan ++; - dest_scan += dest_gap; - } - } else { - FX_ARGB argb = 0; - for (int col = 0; col < pixel_count; col ++) { - argb = pPalette[*src_scan]; - int src_r = FXARGB_R(argb); - int src_g = FXARGB_G(argb); - int src_b = FXARGB_B(argb); - if (clip_scan && clip_scan[col] < 255) { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, clip_scan[col]); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, clip_scan[col]); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, clip_scan[col]); - dest_scan ++; - } else { - *dest_scan++ = src_b; - *dest_scan++ = src_g; - *dest_scan++ = src_r; - } - if (DestBpp == 4) { - dest_scan++; - } - src_scan ++; - } - } -} -inline void _CompositeRow_1bppRgb2Rgb_NoBlend(uint8_t* dest_scan, const uint8_t* src_scan, int src_left, - FX_DWORD* pPalette, int pixel_count, int DestBpp, const uint8_t* clip_scan) -{ - int reset_r, reset_g, reset_b; - int set_r, set_g, set_b; - reset_r = FXARGB_R(pPalette[0]); - reset_g = FXARGB_G(pPalette[0]); - reset_b = FXARGB_B(pPalette[0]); - set_r = FXARGB_R(pPalette[1]); - set_g = FXARGB_G(pPalette[1]); - set_b = FXARGB_B(pPalette[1]); - for (int col = 0; col < pixel_count; col ++) { - int src_r, src_g, src_b; - if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) { - src_r = set_r; - src_g = set_g; - src_b = set_b; - } else { - src_r = reset_r; - src_g = reset_g; - src_b = reset_b; - } - if (clip_scan && clip_scan[col] < 255) { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, clip_scan[col]); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, clip_scan[col]); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, clip_scan[col]); - dest_scan ++; - } else { - *dest_scan++ = src_b; - *dest_scan++ = src_g; - *dest_scan++ = src_r; - } - if (DestBpp == 4) { - dest_scan++; - } - } -} -inline void _CompositeRow_8bppRgb2Argb_NoBlend(uint8_t* dest_scan, const uint8_t* src_scan, int width, - FX_DWORD* pPalette, const uint8_t* clip_scan, - const uint8_t* src_alpha_scan) -{ - if (src_alpha_scan) { - for (int col = 0; col < width; col ++) { - FX_ARGB argb = pPalette[*src_scan]; - src_scan ++; - int src_r = FXARGB_R(argb); - int src_g = FXARGB_G(argb); - int src_b = FXARGB_B(argb); - uint8_t back_alpha = dest_scan[3]; - if (back_alpha == 0) { - if (clip_scan) { - int src_alpha = clip_scan[col] * (*src_alpha_scan) / 255; - FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b)); - } else { - FXARGB_SETDIB(dest_scan, FXARGB_MAKE(*src_alpha_scan, src_r, src_g, src_b)); - } - dest_scan += 4; - src_alpha_scan ++; - continue; - } - uint8_t src_alpha; - if (clip_scan == NULL) { - src_alpha = *src_alpha_scan ++; - } else { - src_alpha = clip_scan[col] * (*src_alpha_scan++) / 255; - } - if (src_alpha == 0) { - dest_scan += 4; - continue; - } - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - dest_scan[3] = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio); - dest_scan ++; - dest_scan ++; - } - } else - for (int col = 0; col < width; col ++) { - FX_ARGB argb = pPalette[*src_scan]; - int src_r = FXARGB_R(argb); - int src_g = FXARGB_G(argb); - int src_b = FXARGB_B(argb); - if (clip_scan == NULL || clip_scan[col] == 255) { - *dest_scan++ = src_b; - *dest_scan++ = src_g; - *dest_scan++ = src_r; - *dest_scan++ = 255; - src_scan ++; - continue; - } - int src_alpha = clip_scan[col]; - if (src_alpha == 0) { - dest_scan += 4; - src_scan ++; - continue; - } - int back_alpha = dest_scan[3]; - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - dest_scan[3] = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio); - dest_scan ++; - dest_scan ++; - src_scan ++; - } -} -void _CompositeRow_8bppRgb2Rgba_NoBlend(uint8_t* dest_scan, const uint8_t* src_scan, int width, - FX_DWORD* pPalette, const uint8_t* clip_scan, - uint8_t* dest_alpha_scan, const uint8_t* src_alpha_scan) -{ - if (src_alpha_scan) { - for (int col = 0; col < width; col ++) { - FX_ARGB argb = pPalette[*src_scan]; - src_scan ++; - int src_r = FXARGB_R(argb); - int src_g = FXARGB_G(argb); - int src_b = FXARGB_B(argb); - uint8_t back_alpha = *dest_alpha_scan; - if (back_alpha == 0) { - if (clip_scan) { - int src_alpha = clip_scan[col] * (*src_alpha_scan) / 255; - *dest_alpha_scan ++ = src_alpha; - } else { - *dest_alpha_scan ++ = *src_alpha_scan; - } - *dest_scan ++ = src_b; - *dest_scan ++ = src_g; - *dest_scan ++ = src_r; - src_alpha_scan ++; - continue; - } - uint8_t src_alpha; - if (clip_scan == NULL) { - src_alpha = *src_alpha_scan++; - } else { - src_alpha = clip_scan[col] * (*src_alpha_scan++) / 255; - } - if (src_alpha == 0) { - dest_scan += 3; - dest_alpha_scan ++; - continue; - } - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - *dest_alpha_scan ++ = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio); - dest_scan ++; - } - } else - for (int col = 0; col < width; col ++) { - FX_ARGB argb = pPalette[*src_scan]; - int src_r = FXARGB_R(argb); - int src_g = FXARGB_G(argb); - int src_b = FXARGB_B(argb); - if (clip_scan == NULL || clip_scan[col] == 255) { - *dest_scan++ = src_b; - *dest_scan++ = src_g; - *dest_scan++ = src_r; - *dest_alpha_scan++ = 255; - src_scan ++; - continue; - } - int src_alpha = clip_scan[col]; - if (src_alpha == 0) { - dest_scan += 3; - dest_alpha_scan ++; - src_scan ++; - continue; - } - int back_alpha = *dest_alpha_scan; - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - *dest_alpha_scan ++ = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio); - dest_scan ++; - src_scan ++; - } -} -inline void _CompositeRow_1bppRgb2Argb_NoBlend(uint8_t* dest_scan, const uint8_t* src_scan, int src_left, int width, - FX_DWORD* pPalette, const uint8_t* clip_scan) -{ - int reset_r, reset_g, reset_b; - int set_r, set_g, set_b; - reset_r = FXARGB_R(pPalette[0]); - reset_g = FXARGB_G(pPalette[0]); - reset_b = FXARGB_B(pPalette[0]); - set_r = FXARGB_R(pPalette[1]); - set_g = FXARGB_G(pPalette[1]); - set_b = FXARGB_B(pPalette[1]); - for (int col = 0; col < width; col ++) { - int src_r, src_g, src_b; - if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) { - src_r = set_r; - src_g = set_g; - src_b = set_b; - } else { - src_r = reset_r; - src_g = reset_g; - src_b = reset_b; - } - if (clip_scan == NULL || clip_scan[col] == 255) { - *dest_scan++ = src_b; - *dest_scan++ = src_g; - *dest_scan++ = src_r; - *dest_scan++ = 255; - continue; - } - int src_alpha = clip_scan[col]; - if (src_alpha == 0) { - dest_scan += 4; - continue; - } - int back_alpha = dest_scan[3]; - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - dest_scan[3] = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio); - dest_scan ++; - dest_scan ++; - } -} -void _CompositeRow_1bppRgb2Rgba_NoBlend(uint8_t* dest_scan, const uint8_t* src_scan, int src_left, int width, - FX_DWORD* pPalette, const uint8_t* clip_scan, - uint8_t* dest_alpha_scan) -{ - int reset_r, reset_g, reset_b; - int set_r, set_g, set_b; - reset_r = FXARGB_R(pPalette[0]); - reset_g = FXARGB_G(pPalette[0]); - reset_b = FXARGB_B(pPalette[0]); - set_r = FXARGB_R(pPalette[1]); - set_g = FXARGB_G(pPalette[1]); - set_b = FXARGB_B(pPalette[1]); - for (int col = 0; col < width; col ++) { - int src_r, src_g, src_b; - if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) { - src_r = set_r; - src_g = set_g; - src_b = set_b; - } else { - src_r = reset_r; - src_g = reset_g; - src_b = reset_b; - } - if (clip_scan == NULL || clip_scan[col] == 255) { - *dest_scan++ = src_b; - *dest_scan++ = src_g; - *dest_scan++ = src_r; - *dest_alpha_scan++ = 255; - continue; - } - int src_alpha = clip_scan[col]; - if (src_alpha == 0) { - dest_scan += 3; - dest_alpha_scan ++; - continue; - } - int back_alpha = *dest_alpha_scan; - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - *dest_alpha_scan ++ = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio); - dest_scan ++; - } -} -void _CompositeRow_ByteMask2Argb(uint8_t* dest_scan, const uint8_t* src_scan, int mask_alpha, int src_r, int src_g, int src_b, int pixel_count, - int blend_type, const uint8_t* clip_scan) -{ - for (int col = 0; col < pixel_count; col ++) { - int src_alpha; - if (clip_scan) { - src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255; - } else { - src_alpha = mask_alpha * src_scan[col] / 255; - } - uint8_t back_alpha = dest_scan[3]; - if (back_alpha == 0) { - FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b)); - dest_scan += 4; - continue; - } - if (src_alpha == 0) { - dest_scan += 4; - continue; - } - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - dest_scan[3] = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - if (blend_type >= FXDIB_BLEND_NONSEPARABLE) { - int blended_colors[3]; - uint8_t src_scan[3]; - src_scan[0] = src_b; - src_scan[1] = src_g; - src_scan[2] = src_r; - _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio); - } else if (blend_type) { - int blended = _BLEND(blend_type, *dest_scan, src_b); - blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); - dest_scan ++; - blended = _BLEND(blend_type, *dest_scan, src_g); - blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); - dest_scan ++; - blended = _BLEND(blend_type, *dest_scan, src_r); - blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); - } else { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio); - } - dest_scan += 2; - } -} -void _CompositeRow_ByteMask2Rgba(uint8_t* dest_scan, const uint8_t* src_scan, int mask_alpha, int src_r, int src_g, int src_b, int pixel_count, - int blend_type, const uint8_t* clip_scan, - uint8_t* dest_alpha_scan) -{ - for (int col = 0; col < pixel_count; col ++) { - int src_alpha; - if (clip_scan) { - src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255; - } else { - src_alpha = mask_alpha * src_scan[col] / 255; - } - uint8_t back_alpha = *dest_alpha_scan; - if (back_alpha == 0) { - *dest_scan ++ = src_b; - *dest_scan ++ = src_g; - *dest_scan ++ = src_r; - *dest_alpha_scan ++ = src_alpha; - continue; - } - if (src_alpha == 0) { - dest_scan += 3; - dest_alpha_scan ++; - continue; - } - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - *dest_alpha_scan ++ = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - if (blend_type >= FXDIB_BLEND_NONSEPARABLE) { - int blended_colors[3]; - uint8_t src_scan[3]; - src_scan[0] = src_b; - src_scan[1] = src_g; - src_scan[2] = src_r; - _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio); - dest_scan ++; - } else if (blend_type) { - int blended = _BLEND(blend_type, *dest_scan, src_b); - blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); - dest_scan ++; - blended = _BLEND(blend_type, *dest_scan, src_g); - blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); - dest_scan ++; - blended = _BLEND(blend_type, *dest_scan, src_r); - blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); - dest_scan ++; - } else { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio); - dest_scan ++; - } - } -} -void _CompositeRow_ByteMask2Rgb(uint8_t* dest_scan, const uint8_t* src_scan, int mask_alpha, int src_r, int src_g, int src_b, int pixel_count, - int blend_type, int Bpp, const uint8_t* clip_scan) -{ - for (int col = 0; col < pixel_count; col ++) { - int src_alpha; - if (clip_scan) { - src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255; - } else { - src_alpha = mask_alpha * src_scan[col] / 255; - } - if (src_alpha == 0) { - dest_scan += Bpp; - continue; - } - if (blend_type >= FXDIB_BLEND_NONSEPARABLE) { - int blended_colors[3]; - uint8_t src_scan[3]; - src_scan[0] = src_b; - src_scan[1] = src_g; - src_scan[2] = src_r; - _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], src_alpha); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], src_alpha); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], src_alpha); - } else if (blend_type) { - int blended = _BLEND(blend_type, *dest_scan, src_b); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha); - dest_scan ++; - blended = _BLEND(blend_type, *dest_scan, src_g); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha); - dest_scan ++; - blended = _BLEND(blend_type, *dest_scan, src_r); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha); - } else { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, src_alpha); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, src_alpha); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, src_alpha); - } - dest_scan += Bpp - 2; - } -} -void _CompositeRow_ByteMask2Mask(uint8_t* dest_scan, const uint8_t* src_scan, int mask_alpha, int pixel_count, - const uint8_t* clip_scan) -{ - for (int col = 0; col < pixel_count; col ++) { - int src_alpha; - if (clip_scan) { - src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255; - } else { - src_alpha = mask_alpha * src_scan[col] / 255; - } - uint8_t back_alpha = *dest_scan; - if (!back_alpha) { - *dest_scan = src_alpha; - } else if (src_alpha) { - *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255; - } - dest_scan ++; - } -} -void _CompositeRow_ByteMask2Gray(uint8_t* dest_scan, const uint8_t* src_scan, int mask_alpha, int src_gray, - int pixel_count, const uint8_t* clip_scan) -{ - for (int col = 0; col < pixel_count; col ++) { - int src_alpha; - if (clip_scan) { - src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255; - } else { - src_alpha = mask_alpha * src_scan[col] / 255; - } - if (src_alpha) { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_gray, src_alpha); - } - dest_scan ++; - } -} -void _CompositeRow_ByteMask2Graya(uint8_t* dest_scan, const uint8_t* src_scan, int mask_alpha, int src_gray, - int pixel_count, const uint8_t* clip_scan, - uint8_t* dest_alpha_scan) -{ - for (int col = 0; col < pixel_count; col ++) { - int src_alpha; - if (clip_scan) { - src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255; - } else { - src_alpha = mask_alpha * src_scan[col] / 255; - } - uint8_t back_alpha = *dest_alpha_scan; - if (back_alpha == 0) { - *dest_scan ++ = src_gray; - *dest_alpha_scan ++ = src_alpha; - continue; - } - if (src_alpha == 0) { - dest_scan ++; - dest_alpha_scan ++; - continue; - } - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - *dest_alpha_scan++ = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_gray, alpha_ratio); - dest_scan ++; - } -} -void _CompositeRow_BitMask2Argb(uint8_t* dest_scan, const uint8_t* src_scan, int mask_alpha, int src_r, int src_g, int src_b, - int src_left, int pixel_count, int blend_type, const uint8_t* clip_scan) -{ - if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && mask_alpha == 255) { - FX_ARGB argb = FXARGB_MAKE(0xff, src_r, src_g, src_b); - for (int col = 0; col < pixel_count; col ++) { - if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) { - FXARGB_SETDIB(dest_scan, argb); - } - dest_scan += 4; - } - return; - } - for (int col = 0; col < pixel_count; col ++) { - if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) { - dest_scan += 4; - continue; - } - int src_alpha; - if (clip_scan) { - src_alpha = mask_alpha * clip_scan[col] / 255; - } else { - src_alpha = mask_alpha; - } - uint8_t back_alpha = dest_scan[3]; - if (back_alpha == 0) { - FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b)); - dest_scan += 4; - continue; - } - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - dest_scan[3] = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - if (blend_type >= FXDIB_BLEND_NONSEPARABLE) { - int blended_colors[3]; - uint8_t src_scan[3]; - src_scan[0] = src_b; - src_scan[1] = src_g; - src_scan[2] = src_r; - _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio); - } else if (blend_type) { - int blended = _BLEND(blend_type, *dest_scan, src_b); - blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); - dest_scan ++; - blended = _BLEND(blend_type, *dest_scan, src_g); - blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); - dest_scan ++; - blended = _BLEND(blend_type, *dest_scan, src_r); - blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); - } else { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio); - } - dest_scan += 2; - } -} -void _CompositeRow_BitMask2Rgba(uint8_t* dest_scan, const uint8_t* src_scan, int mask_alpha, int src_r, int src_g, int src_b, - int src_left, int pixel_count, int blend_type, const uint8_t* clip_scan, - uint8_t* dest_alpha_scan) -{ - if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && mask_alpha == 255) { - for (int col = 0; col < pixel_count; col ++) { - if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) { - dest_scan[0] = src_b; - dest_scan[1] = src_g; - dest_scan[2] = src_r; - *dest_alpha_scan = mask_alpha; - } - dest_scan += 3; - dest_alpha_scan ++; - } - return; - } - for (int col = 0; col < pixel_count; col ++) { - if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) { - dest_scan += 3; - dest_alpha_scan ++; - continue; - } - int src_alpha; - if (clip_scan) { - src_alpha = mask_alpha * clip_scan[col] / 255; - } else { - src_alpha = mask_alpha; - } - uint8_t back_alpha = dest_scan[3]; - if (back_alpha == 0) { - *dest_scan ++ = src_b; - *dest_scan ++ = src_g; - *dest_scan ++ = src_r; - *dest_alpha_scan ++ = mask_alpha; - continue; - } - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - *dest_alpha_scan ++ = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - if (blend_type >= FXDIB_BLEND_NONSEPARABLE) { - int blended_colors[3]; - uint8_t src_scan[3]; - src_scan[0] = src_b; - src_scan[1] = src_g; - src_scan[2] = src_r; - _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio); - dest_scan ++; - } else if (blend_type) { - int blended = _BLEND(blend_type, *dest_scan, src_b); - blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); - dest_scan ++; - blended = _BLEND(blend_type, *dest_scan, src_g); - blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); - dest_scan ++; - blended = _BLEND(blend_type, *dest_scan, src_r); - blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); - dest_scan ++; - } else { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio); - dest_scan ++; - } - } -} -void _CompositeRow_BitMask2Rgb(uint8_t* dest_scan, const uint8_t* src_scan, int mask_alpha, int src_r, int src_g, int src_b, - int src_left, int pixel_count, int blend_type, int Bpp, const uint8_t* clip_scan) -{ - if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && mask_alpha == 255) { - for (int col = 0; col < pixel_count; col ++) { - if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) { - dest_scan[2] = src_r; - dest_scan[1] = src_g; - dest_scan[0] = src_b; - } - dest_scan += Bpp; - } - return; - } - for (int col = 0; col < pixel_count; col ++) { - if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) { - dest_scan += Bpp; - continue; - } - int src_alpha; - if (clip_scan) { - src_alpha = mask_alpha * clip_scan[col] / 255; - } else { - src_alpha = mask_alpha; - } - if (src_alpha == 0) { - dest_scan += Bpp; - continue; - } - if (blend_type >= FXDIB_BLEND_NONSEPARABLE) { - int blended_colors[3]; - uint8_t src_scan[3]; - src_scan[0] = src_b; - src_scan[1] = src_g; - src_scan[2] = src_r; - _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], src_alpha); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], src_alpha); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], src_alpha); - } else if (blend_type) { - int blended = _BLEND(blend_type, *dest_scan, src_b); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha); - dest_scan++; - blended = _BLEND(blend_type, *dest_scan, src_g); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha); - dest_scan++; - blended = _BLEND(blend_type, *dest_scan, src_r); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha); - } else { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, src_alpha); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, src_alpha); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, src_alpha); - } - dest_scan += Bpp - 2; - } -} -void _CompositeRow_BitMask2Mask(uint8_t* dest_scan, const uint8_t* src_scan, int mask_alpha, int src_left, - int pixel_count, const uint8_t* clip_scan) -{ - for (int col = 0; col < pixel_count; col ++) { - if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) { - dest_scan ++; - continue; - } - int src_alpha; - if (clip_scan) { - src_alpha = mask_alpha * clip_scan[col] / 255; - } else { - src_alpha = mask_alpha; - } - uint8_t back_alpha = *dest_scan; - if (!back_alpha) { - *dest_scan = src_alpha; - } else if (src_alpha) { - *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255; - } - dest_scan ++; - } -} -void _CompositeRow_BitMask2Gray(uint8_t* dest_scan, const uint8_t* src_scan, int mask_alpha, int src_gray, - int src_left, int pixel_count, const uint8_t* clip_scan) -{ - for (int col = 0; col < pixel_count; col ++) { - if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) { - dest_scan ++; - continue; - } - int src_alpha; - if (clip_scan) { - src_alpha = mask_alpha * clip_scan[col] / 255; - } else { - src_alpha = mask_alpha; - } - if (src_alpha) { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_gray, src_alpha); - } - dest_scan ++; - } -} -void _CompositeRow_BitMask2Graya(uint8_t* dest_scan, const uint8_t* src_scan, int mask_alpha, int src_gray, - int src_left, int pixel_count, const uint8_t* clip_scan, - uint8_t* dest_alpha_scan) -{ - for (int col = 0; col < pixel_count; col ++) { - if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) { - dest_scan ++; - dest_alpha_scan ++; - continue; - } - int src_alpha; - if (clip_scan) { - src_alpha = mask_alpha * clip_scan[col] / 255; - } else { - src_alpha = mask_alpha; - } - uint8_t back_alpha = *dest_alpha_scan; - if (back_alpha == 0) { - *dest_scan ++ = src_gray; - *dest_alpha_scan ++ = src_alpha; - continue; - } - if (src_alpha == 0) { - dest_scan ++; - dest_alpha_scan ++; - continue; - } - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - *dest_alpha_scan++ = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_gray, alpha_ratio); - dest_scan ++; - } -} -void _CompositeRow_Argb2Argb_RgbByteOrder(uint8_t* dest_scan, const uint8_t* src_scan, int pixel_count, int blend_type, const uint8_t* clip_scan) -{ - int blended_colors[3]; - FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; - for (int col = 0; col < pixel_count; col ++) { - uint8_t back_alpha = dest_scan[3]; - if (back_alpha == 0) { - if (clip_scan) { - int src_alpha = clip_scan[col] * src_scan[3] / 255; - dest_scan[3] = src_alpha; - dest_scan[0] = src_scan[2]; - dest_scan[1] = src_scan[1]; - dest_scan[2] = src_scan[0]; - } else { - FXARGB_RGBORDERCOPY(dest_scan, src_scan); - } - dest_scan += 4; - src_scan += 4; - continue; - } - uint8_t src_alpha; - if (clip_scan == NULL) { - src_alpha = src_scan[3]; - } else { - src_alpha = clip_scan[col] * src_scan[3] / 255; - } - if (src_alpha == 0) { - dest_scan += 4; - src_scan += 4; - continue; - } - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - dest_scan[3] = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - if (bNonseparableBlend) { - uint8_t dest_scan_o[3]; - dest_scan_o[0] = dest_scan[2]; - dest_scan_o[1] = dest_scan[1]; - dest_scan_o[2] = dest_scan[0]; - _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors); - } - for (int color = 0; color < 3; color ++) { - int index = 2 - color; - if (blend_type) { - int blended = bNonseparableBlend ? blended_colors[color] : - _BLEND(blend_type, dest_scan[index], *src_scan); - blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha); - dest_scan[index] = FXDIB_ALPHA_MERGE(dest_scan[index], blended, alpha_ratio); - } else { - dest_scan[index] = FXDIB_ALPHA_MERGE(dest_scan[index], *src_scan, alpha_ratio); - } - src_scan ++; - } - dest_scan += 4; - src_scan++; - } -} -void _CompositeRow_Rgb2Argb_Blend_NoClip_RgbByteOrder(uint8_t* dest_scan, const uint8_t* src_scan, int width, int blend_type, int src_Bpp) -{ - int blended_colors[3]; - FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; - int src_gap = src_Bpp - 3; - for (int col = 0; col < width; col ++) { - uint8_t back_alpha = dest_scan[3]; - if (back_alpha == 0) { - if (src_Bpp == 4) { - FXARGB_SETRGBORDERDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan)); - } else { - FXARGB_SETRGBORDERDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[2], src_scan[1], src_scan[0])); - } - dest_scan += 4; - src_scan += src_Bpp; - continue; - } - dest_scan[3] = 0xff; - if (bNonseparableBlend) { - uint8_t dest_scan_o[3]; - dest_scan_o[0] = dest_scan[2]; - dest_scan_o[1] = dest_scan[1]; - dest_scan_o[2] = dest_scan[0]; - _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors); - } - for (int color = 0; color < 3; color ++) { - int index = 2 - color; - int src_color = FX_GAMMA(*src_scan); - int blended = bNonseparableBlend ? blended_colors[color] : - _BLEND(blend_type, dest_scan[index], src_color); - dest_scan[index] = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha); - src_scan ++; + *dest_alpha_scan = + back_alpha + src_alpha - back_alpha * src_alpha / 255; + int alpha_ratio = src_alpha * 255 / (*dest_alpha_scan); + if (bNonseparableBlend) { + blended_color = + blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan; } - dest_scan += 4; - src_scan += src_gap; - } -} -inline void _CompositeRow_Argb2Rgb_Blend_RgbByteOrder(uint8_t* dest_scan, const uint8_t* src_scan, int width, int blend_type, int dest_Bpp, const uint8_t* clip_scan) -{ - int blended_colors[3]; - FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; - for (int col = 0; col < width; col ++) { - uint8_t src_alpha; + gray = bNonseparableBlend ? blended_color + : _BLEND(blend_type, *dest_scan, gray); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio); + dest_alpha_scan++; + dest_scan++; + } + return; + } + for (int col = 0; col < pixel_count; col++) { + uint8_t gray = pPalette[*src_scan]; + src_scan++; + uint8_t back_alpha = *dest_alpha_scan; + if (back_alpha == 0) { + int src_alpha = *src_alpha_scan++; if (clip_scan) { - src_alpha = src_scan[3] * (*clip_scan++) / 255; - } else { - src_alpha = src_scan[3]; + src_alpha = clip_scan[col] * src_alpha / 255; + } + if (src_alpha) { + *dest_scan = gray; + *dest_alpha_scan = src_alpha; + } + dest_scan++; + dest_alpha_scan++; + continue; + } + uint8_t src_alpha = *src_alpha_scan++; + if (clip_scan) { + src_alpha = clip_scan[col] * src_alpha / 255; + } + if (src_alpha == 0) { + dest_scan++; + dest_alpha_scan++; + continue; + } + *dest_alpha_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255; + int alpha_ratio = src_alpha * 255 / (*dest_alpha_scan); + dest_alpha_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio); + dest_scan++; + } + } else { + if (blend_type) { + FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; + int blended_color; + for (int col = 0; col < pixel_count; col++) { + uint8_t gray = pPalette[*src_scan]; + src_scan++; + if (clip_scan == NULL || clip_scan[col] == 255) { + *dest_scan++ = gray; + *dest_alpha_scan++ = 255; + continue; } + int src_alpha = clip_scan[col]; if (src_alpha == 0) { - dest_scan += dest_Bpp; - src_scan += 4; - continue; + dest_scan++; + dest_alpha_scan++; + continue; } + int back_alpha = *dest_alpha_scan; + uint8_t dest_alpha = + back_alpha + src_alpha - back_alpha * src_alpha / 255; + *dest_alpha_scan++ = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; if (bNonseparableBlend) { - uint8_t dest_scan_o[3]; - dest_scan_o[0] = dest_scan[2]; - dest_scan_o[1] = dest_scan[1]; - dest_scan_o[2] = dest_scan[0]; - _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors); + blended_color = + blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan; } - for (int color = 0; color < 3; color ++) { - int index = 2 - color; - int back_color = FX_GAMMA(dest_scan[index]); - int blended = bNonseparableBlend ? blended_colors[color] : - _BLEND(blend_type, back_color, *src_scan); - dest_scan[index] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha)); - src_scan ++; - } - dest_scan += dest_Bpp; - src_scan ++; - } + gray = bNonseparableBlend ? blended_color + : _BLEND(blend_type, *dest_scan, gray); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio); + dest_scan++; + } + return; + } + for (int col = 0; col < pixel_count; col++) { + uint8_t gray = pPalette[*src_scan]; + src_scan++; + if (clip_scan == NULL || clip_scan[col] == 255) { + *dest_scan++ = gray; + *dest_alpha_scan++ = 255; + continue; + } + int src_alpha = clip_scan[col]; + if (src_alpha == 0) { + dest_scan++; + dest_alpha_scan++; + continue; + } + int back_alpha = *dest_alpha_scan; + uint8_t dest_alpha = + back_alpha + src_alpha - back_alpha * src_alpha / 255; + *dest_alpha_scan++ = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio); + dest_scan++; + } + } } -inline void _CompositeRow_Rgb2Argb_NoBlend_NoClip_RgbByteOrder(uint8_t* dest_scan, const uint8_t* src_scan, int width, int src_Bpp) -{ - for (int col = 0; col < width; col ++) { - if (src_Bpp == 4) { - FXARGB_SETRGBORDERDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan)); - } else { - FXARGB_SETRGBORDERDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[2], src_scan[1], src_scan[0])); - } - dest_scan += 4; - src_scan += src_Bpp; +inline void _CompositeRow_1bppPal2Gray(uint8_t* dest_scan, + const uint8_t* src_scan, + int src_left, + const uint8_t* pPalette, + int pixel_count, + int blend_type, + const uint8_t* clip_scan) { + int reset_gray = pPalette[0]; + int set_gray = pPalette[1]; + if (blend_type) { + FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; + int blended_color; + for (int col = 0; col < pixel_count; col++) { + uint8_t gray = + (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) + ? set_gray + : reset_gray; + if (bNonseparableBlend) { + blended_color = + blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan; + } + gray = bNonseparableBlend ? blended_color + : _BLEND(blend_type, *dest_scan, gray); + if (clip_scan && clip_scan[col] < 255) { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]); + } else { + *dest_scan = gray; + } + dest_scan++; + } + return; + } + for (int col = 0; col < pixel_count; col++) { + uint8_t gray = + (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) + ? set_gray + : reset_gray; + if (clip_scan && clip_scan[col] < 255) { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]); + } else { + *dest_scan = gray; } + dest_scan++; + } } -inline void _CompositeRow_Rgb2Rgb_Blend_NoClip_RgbByteOrder(uint8_t* dest_scan, const uint8_t* src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp) -{ - int blended_colors[3]; +inline void _CompositeRow_1bppPal2Graya(uint8_t* dest_scan, + const uint8_t* src_scan, + int src_left, + const uint8_t* pPalette, + int pixel_count, + int blend_type, + const uint8_t* clip_scan, + uint8_t* dest_alpha_scan) { + int reset_gray = pPalette[0]; + int set_gray = pPalette[1]; + if (blend_type) { FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; - int src_gap = src_Bpp - 3; - for (int col = 0; col < width; col ++) { - if (bNonseparableBlend) { - uint8_t dest_scan_o[3]; - dest_scan_o[0] = dest_scan[2]; - dest_scan_o[1] = dest_scan[1]; - dest_scan_o[2] = dest_scan[0]; - _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors); - } - for (int color = 0; color < 3; color ++) { - int index = 2 - color; - int back_color = FX_GAMMA(dest_scan[index]); - int src_color = FX_GAMMA(*src_scan); - int blended = bNonseparableBlend ? blended_colors[color] : - _BLEND(blend_type, back_color, src_color); - dest_scan[index] = FX_GAMMA_INVERSE(blended); - src_scan ++; - } - dest_scan += dest_Bpp; - src_scan += src_gap; - } + int blended_color; + for (int col = 0; col < pixel_count; col++) { + uint8_t gray = + (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) + ? set_gray + : reset_gray; + if (clip_scan == NULL || clip_scan[col] == 255) { + *dest_scan++ = gray; + *dest_alpha_scan++ = 255; + continue; + } + int src_alpha = clip_scan[col]; + if (src_alpha == 0) { + dest_scan++; + dest_alpha_scan++; + continue; + } + int back_alpha = *dest_alpha_scan; + uint8_t dest_alpha = + back_alpha + src_alpha - back_alpha * src_alpha / 255; + *dest_alpha_scan++ = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + if (bNonseparableBlend) { + blended_color = + blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan; + } + gray = bNonseparableBlend ? blended_color + : _BLEND(blend_type, *dest_scan, gray); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio); + dest_scan++; + } + return; + } + for (int col = 0; col < pixel_count; col++) { + uint8_t gray = + (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) + ? set_gray + : reset_gray; + if (clip_scan == NULL || clip_scan[col] == 255) { + *dest_scan++ = gray; + *dest_alpha_scan++ = 255; + continue; + } + int src_alpha = clip_scan[col]; + if (src_alpha == 0) { + dest_scan++; + dest_alpha_scan++; + continue; + } + int back_alpha = *dest_alpha_scan; + uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; + *dest_alpha_scan++ = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio); + dest_scan++; + } } -inline void _CompositeRow_Argb2Rgb_NoBlend_RgbByteOrder(uint8_t* dest_scan, const uint8_t* src_scan, int width, int dest_Bpp, const uint8_t* clip_scan) -{ - for (int col = 0; col < width; col ++) { - uint8_t src_alpha; - if (clip_scan) { - src_alpha = src_scan[3] * (*clip_scan++) / 255; - } else { - src_alpha = src_scan[3]; - } - if (src_alpha == 255) { - dest_scan[2] = FX_GAMMA_INVERSE(*src_scan++); - dest_scan[1] = FX_GAMMA_INVERSE(*src_scan++); - dest_scan[0] = FX_GAMMA_INVERSE(*src_scan++); - dest_scan += dest_Bpp; - src_scan ++; - continue; - } - if (src_alpha == 0) { - dest_scan += dest_Bpp; - src_scan += 4; - continue; - } - for (int color = 0; color < 3; color ++) { - int index = 2 - color; - dest_scan[index] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[index]), *src_scan, src_alpha)); - src_scan ++; - } - dest_scan += dest_Bpp; - src_scan ++; - } +inline void _CompositeRow_8bppRgb2Rgb_NoBlend(uint8_t* dest_scan, + const uint8_t* src_scan, + FX_DWORD* pPalette, + int pixel_count, + int DestBpp, + const uint8_t* clip_scan, + const uint8_t* src_alpha_scan) { + if (src_alpha_scan) { + int dest_gap = DestBpp - 3; + FX_ARGB argb = 0; + for (int col = 0; col < pixel_count; col++) { + argb = pPalette[*src_scan]; + int src_r = FXARGB_R(argb); + int src_g = FXARGB_G(argb); + int src_b = FXARGB_B(argb); + src_scan++; + uint8_t src_alpha = 0; + if (clip_scan) { + src_alpha = (*src_alpha_scan++) * (*clip_scan++) / 255; + } else { + src_alpha = *src_alpha_scan++; + } + if (src_alpha == 255) { + *dest_scan++ = src_b; + *dest_scan++ = src_g; + *dest_scan++ = src_r; + dest_scan += dest_gap; + continue; + } + if (src_alpha == 0) { + dest_scan += DestBpp; + continue; + } + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, src_alpha); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, src_alpha); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, src_alpha); + dest_scan++; + dest_scan += dest_gap; + } + } else { + FX_ARGB argb = 0; + for (int col = 0; col < pixel_count; col++) { + argb = pPalette[*src_scan]; + int src_r = FXARGB_R(argb); + int src_g = FXARGB_G(argb); + int src_b = FXARGB_B(argb); + if (clip_scan && clip_scan[col] < 255) { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, clip_scan[col]); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, clip_scan[col]); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, clip_scan[col]); + dest_scan++; + } else { + *dest_scan++ = src_b; + *dest_scan++ = src_g; + *dest_scan++ = src_r; + } + if (DestBpp == 4) { + dest_scan++; + } + src_scan++; + } + } } -inline void _CompositeRow_Rgb2Rgb_NoBlend_NoClip_RgbByteOrder(uint8_t* dest_scan, const uint8_t* src_scan, int width, int dest_Bpp, int src_Bpp) -{ - for (int col = 0; col < width; col ++) { - dest_scan[2] = src_scan[0]; - dest_scan[1] = src_scan[1]; - dest_scan[0] = src_scan[2]; - dest_scan += dest_Bpp; - src_scan += src_Bpp; +inline void _CompositeRow_1bppRgb2Rgb_NoBlend(uint8_t* dest_scan, + const uint8_t* src_scan, + int src_left, + FX_DWORD* pPalette, + int pixel_count, + int DestBpp, + const uint8_t* clip_scan) { + int reset_r, reset_g, reset_b; + int set_r, set_g, set_b; + reset_r = FXARGB_R(pPalette[0]); + reset_g = FXARGB_G(pPalette[0]); + reset_b = FXARGB_B(pPalette[0]); + set_r = FXARGB_R(pPalette[1]); + set_g = FXARGB_G(pPalette[1]); + set_b = FXARGB_B(pPalette[1]); + for (int col = 0; col < pixel_count; col++) { + int src_r, src_g, src_b; + if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) { + src_r = set_r; + src_g = set_g; + src_b = set_b; + } else { + src_r = reset_r; + src_g = reset_g; + src_b = reset_b; + } + if (clip_scan && clip_scan[col] < 255) { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, clip_scan[col]); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, clip_scan[col]); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, clip_scan[col]); + dest_scan++; + } else { + *dest_scan++ = src_b; + *dest_scan++ = src_g; + *dest_scan++ = src_r; + } + if (DestBpp == 4) { + dest_scan++; } + } } -inline void _CompositeRow_Rgb2Argb_Blend_Clip_RgbByteOrder(uint8_t* dest_scan, const uint8_t* src_scan, int width, int blend_type, int src_Bpp, const uint8_t* clip_scan) -{ - int blended_colors[3]; - FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; - int src_gap = src_Bpp - 3; - for (int col = 0; col < width; col ++) { - int src_alpha = *clip_scan ++; - uint8_t back_alpha = dest_scan[3]; - if (back_alpha == 0) { - dest_scan[2] = FX_GAMMA(*src_scan++); - dest_scan[1] = FX_GAMMA(*src_scan++); - dest_scan[0] = FX_GAMMA(*src_scan++); - src_scan += src_gap; - dest_scan += 4; - continue; - } - if (src_alpha == 0) { - dest_scan += 4; - src_scan += src_Bpp; - continue; - } - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - dest_scan[3] = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - if (bNonseparableBlend) { - uint8_t dest_scan_o[3]; - dest_scan_o[0] = dest_scan[2]; - dest_scan_o[1] = dest_scan[1]; - dest_scan_o[2] = dest_scan[0]; - _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors); - } - for (int color = 0; color < 3; color ++) { - int index = 2 - color; - int src_color = FX_GAMMA(*src_scan); - int blended = bNonseparableBlend ? blended_colors[color] : - _BLEND(blend_type, dest_scan[index], src_color); - blended = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha); - dest_scan[index] = FXDIB_ALPHA_MERGE(dest_scan[index], blended, alpha_ratio); - src_scan ++; +inline void _CompositeRow_8bppRgb2Argb_NoBlend(uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + FX_DWORD* pPalette, + const uint8_t* clip_scan, + const uint8_t* src_alpha_scan) { + if (src_alpha_scan) { + for (int col = 0; col < width; col++) { + FX_ARGB argb = pPalette[*src_scan]; + src_scan++; + int src_r = FXARGB_R(argb); + int src_g = FXARGB_G(argb); + int src_b = FXARGB_B(argb); + uint8_t back_alpha = dest_scan[3]; + if (back_alpha == 0) { + if (clip_scan) { + int src_alpha = clip_scan[col] * (*src_alpha_scan) / 255; + FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b)); + } else { + FXARGB_SETDIB(dest_scan, + FXARGB_MAKE(*src_alpha_scan, src_r, src_g, src_b)); } dest_scan += 4; - src_scan += src_gap; + src_alpha_scan++; + continue; + } + uint8_t src_alpha; + if (clip_scan == NULL) { + src_alpha = *src_alpha_scan++; + } else { + src_alpha = clip_scan[col] * (*src_alpha_scan++) / 255; + } + if (src_alpha == 0) { + dest_scan += 4; + continue; + } + uint8_t dest_alpha = + back_alpha + src_alpha - back_alpha * src_alpha / 255; + dest_scan[3] = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio); + dest_scan++; + dest_scan++; + } + } else + for (int col = 0; col < width; col++) { + FX_ARGB argb = pPalette[*src_scan]; + int src_r = FXARGB_R(argb); + int src_g = FXARGB_G(argb); + int src_b = FXARGB_B(argb); + if (clip_scan == NULL || clip_scan[col] == 255) { + *dest_scan++ = src_b; + *dest_scan++ = src_g; + *dest_scan++ = src_r; + *dest_scan++ = 255; + src_scan++; + continue; + } + int src_alpha = clip_scan[col]; + if (src_alpha == 0) { + dest_scan += 4; + src_scan++; + continue; + } + int back_alpha = dest_scan[3]; + uint8_t dest_alpha = + back_alpha + src_alpha - back_alpha * src_alpha / 255; + dest_scan[3] = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio); + dest_scan++; + dest_scan++; + src_scan++; } } -inline void _CompositeRow_Rgb2Rgb_Blend_Clip_RgbByteOrder(uint8_t* dest_scan, const uint8_t* src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp, const uint8_t* clip_scan) -{ - int blended_colors[3]; - FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; - int src_gap = src_Bpp - 3; - for (int col = 0; col < width; col ++) { - uint8_t src_alpha = *clip_scan ++; - if (src_alpha == 0) { - dest_scan += dest_Bpp; - src_scan += src_Bpp; - continue; - } - if (bNonseparableBlend) { - uint8_t dest_scan_o[3]; - dest_scan_o[0] = dest_scan[2]; - dest_scan_o[1] = dest_scan[1]; - dest_scan_o[2] = dest_scan[0]; - _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors); - } - for (int color = 0; color < 3; color ++) { - int index = 2 - color; - int src_color = FX_GAMMA(*src_scan); - int back_color = FX_GAMMA(dest_scan[index]); - int blended = bNonseparableBlend ? blended_colors[color] : - _BLEND(blend_type, back_color, src_color); - dest_scan[index] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha)); - src_scan ++; - } - dest_scan += dest_Bpp; - src_scan += src_gap; +void _CompositeRow_8bppRgb2Rgba_NoBlend(uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + FX_DWORD* pPalette, + const uint8_t* clip_scan, + uint8_t* dest_alpha_scan, + const uint8_t* src_alpha_scan) { + if (src_alpha_scan) { + for (int col = 0; col < width; col++) { + FX_ARGB argb = pPalette[*src_scan]; + src_scan++; + int src_r = FXARGB_R(argb); + int src_g = FXARGB_G(argb); + int src_b = FXARGB_B(argb); + uint8_t back_alpha = *dest_alpha_scan; + if (back_alpha == 0) { + if (clip_scan) { + int src_alpha = clip_scan[col] * (*src_alpha_scan) / 255; + *dest_alpha_scan++ = src_alpha; + } else { + *dest_alpha_scan++ = *src_alpha_scan; + } + *dest_scan++ = src_b; + *dest_scan++ = src_g; + *dest_scan++ = src_r; + src_alpha_scan++; + continue; + } + uint8_t src_alpha; + if (clip_scan == NULL) { + src_alpha = *src_alpha_scan++; + } else { + src_alpha = clip_scan[col] * (*src_alpha_scan++) / 255; + } + if (src_alpha == 0) { + dest_scan += 3; + dest_alpha_scan++; + continue; + } + uint8_t dest_alpha = + back_alpha + src_alpha - back_alpha * src_alpha / 255; + *dest_alpha_scan++ = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio); + dest_scan++; + } + } else + for (int col = 0; col < width; col++) { + FX_ARGB argb = pPalette[*src_scan]; + int src_r = FXARGB_R(argb); + int src_g = FXARGB_G(argb); + int src_b = FXARGB_B(argb); + if (clip_scan == NULL || clip_scan[col] == 255) { + *dest_scan++ = src_b; + *dest_scan++ = src_g; + *dest_scan++ = src_r; + *dest_alpha_scan++ = 255; + src_scan++; + continue; + } + int src_alpha = clip_scan[col]; + if (src_alpha == 0) { + dest_scan += 3; + dest_alpha_scan++; + src_scan++; + continue; + } + int back_alpha = *dest_alpha_scan; + uint8_t dest_alpha = + back_alpha + src_alpha - back_alpha * src_alpha / 255; + *dest_alpha_scan++ = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio); + dest_scan++; + src_scan++; } } -inline void _CompositeRow_Rgb2Argb_NoBlend_Clip_RgbByteOrder(uint8_t* dest_scan, const uint8_t* src_scan, int width, int src_Bpp, const uint8_t* clip_scan) -{ - int src_gap = src_Bpp - 3; - for (int col = 0; col < width; col ++) { - int src_alpha = clip_scan[col]; - if (src_alpha == 255) { - dest_scan[2] = FX_GAMMA(*src_scan++); - dest_scan[1] = FX_GAMMA(*src_scan++); - dest_scan[0] = FX_GAMMA(*src_scan++); - dest_scan[3] = 255; - dest_scan += 4; - src_scan += src_gap; - continue; - } - if (src_alpha == 0) { - dest_scan += 4; - src_scan += src_Bpp; - continue; - } - int back_alpha = dest_scan[3]; - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - dest_scan[3] = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - for (int color = 0; color < 3; color ++) { - int index = 2 - color; - dest_scan[index] = FXDIB_ALPHA_MERGE(dest_scan[index], FX_GAMMA(*src_scan), alpha_ratio); - src_scan ++; - } - dest_scan += 4; - src_scan += src_gap; - } +inline void _CompositeRow_1bppRgb2Argb_NoBlend(uint8_t* dest_scan, + const uint8_t* src_scan, + int src_left, + int width, + FX_DWORD* pPalette, + const uint8_t* clip_scan) { + int reset_r, reset_g, reset_b; + int set_r, set_g, set_b; + reset_r = FXARGB_R(pPalette[0]); + reset_g = FXARGB_G(pPalette[0]); + reset_b = FXARGB_B(pPalette[0]); + set_r = FXARGB_R(pPalette[1]); + set_g = FXARGB_G(pPalette[1]); + set_b = FXARGB_B(pPalette[1]); + for (int col = 0; col < width; col++) { + int src_r, src_g, src_b; + if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) { + src_r = set_r; + src_g = set_g; + src_b = set_b; + } else { + src_r = reset_r; + src_g = reset_g; + src_b = reset_b; + } + if (clip_scan == NULL || clip_scan[col] == 255) { + *dest_scan++ = src_b; + *dest_scan++ = src_g; + *dest_scan++ = src_r; + *dest_scan++ = 255; + continue; + } + int src_alpha = clip_scan[col]; + if (src_alpha == 0) { + dest_scan += 4; + continue; + } + int back_alpha = dest_scan[3]; + uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; + dest_scan[3] = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio); + dest_scan++; + dest_scan++; + } } -inline void _CompositeRow_Rgb2Rgb_NoBlend_Clip_RgbByteOrder(uint8_t* dest_scan, const uint8_t* src_scan, int width, int dest_Bpp, int src_Bpp, const uint8_t* clip_scan) -{ - for (int col = 0; col < width; col ++) { - int src_alpha = clip_scan[col]; - if (src_alpha == 255) { - dest_scan[2] = src_scan[0]; - dest_scan[1] = src_scan[1]; - dest_scan[0] = src_scan[2]; - } else if (src_alpha) { - dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), FX_GAMMA(*src_scan), src_alpha)); - src_scan ++; - dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), FX_GAMMA(*src_scan), src_alpha)); - src_scan ++; - dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), FX_GAMMA(*src_scan), src_alpha)); - dest_scan += dest_Bpp; - src_scan += src_Bpp - 2; - continue; - } - dest_scan += dest_Bpp; - src_scan += src_Bpp; - } +void _CompositeRow_1bppRgb2Rgba_NoBlend(uint8_t* dest_scan, + const uint8_t* src_scan, + int src_left, + int width, + FX_DWORD* pPalette, + const uint8_t* clip_scan, + uint8_t* dest_alpha_scan) { + int reset_r, reset_g, reset_b; + int set_r, set_g, set_b; + reset_r = FXARGB_R(pPalette[0]); + reset_g = FXARGB_G(pPalette[0]); + reset_b = FXARGB_B(pPalette[0]); + set_r = FXARGB_R(pPalette[1]); + set_g = FXARGB_G(pPalette[1]); + set_b = FXARGB_B(pPalette[1]); + for (int col = 0; col < width; col++) { + int src_r, src_g, src_b; + if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) { + src_r = set_r; + src_g = set_g; + src_b = set_b; + } else { + src_r = reset_r; + src_g = reset_g; + src_b = reset_b; + } + if (clip_scan == NULL || clip_scan[col] == 255) { + *dest_scan++ = src_b; + *dest_scan++ = src_g; + *dest_scan++ = src_r; + *dest_alpha_scan++ = 255; + continue; + } + int src_alpha = clip_scan[col]; + if (src_alpha == 0) { + dest_scan += 3; + dest_alpha_scan++; + continue; + } + int back_alpha = *dest_alpha_scan; + uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; + *dest_alpha_scan++ = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio); + dest_scan++; + } } -inline void _CompositeRow_8bppRgb2Rgb_NoBlend_RgbByteOrder(uint8_t* dest_scan, const uint8_t* src_scan, FX_ARGB* pPalette, int pixel_count, - int DestBpp, const uint8_t* clip_scan) -{ - for (int col = 0; col < pixel_count; col ++) { - FX_ARGB argb = pPalette ? pPalette[*src_scan] : (*src_scan) * 0x010101; - int src_r = FXARGB_R(argb); - int src_g = FXARGB_G(argb); - int src_b = FXARGB_B(argb); - if (clip_scan && clip_scan[col] < 255) { - dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, clip_scan[col]); - dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, clip_scan[col]); - dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, clip_scan[col]); - } else { - dest_scan[2] = src_b; - dest_scan[1] = src_g; - dest_scan[0] = src_r; - } - dest_scan += DestBpp; - src_scan ++; +void _CompositeRow_ByteMask2Argb(uint8_t* dest_scan, + const uint8_t* src_scan, + int mask_alpha, + int src_r, + int src_g, + int src_b, + int pixel_count, + int blend_type, + const uint8_t* clip_scan) { + for (int col = 0; col < pixel_count; col++) { + int src_alpha; + if (clip_scan) { + src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255; + } else { + src_alpha = mask_alpha * src_scan[col] / 255; + } + uint8_t back_alpha = dest_scan[3]; + if (back_alpha == 0) { + FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b)); + dest_scan += 4; + continue; } + if (src_alpha == 0) { + dest_scan += 4; + continue; + } + uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; + dest_scan[3] = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + if (blend_type >= FXDIB_BLEND_NONSEPARABLE) { + int blended_colors[3]; + uint8_t src_scan[3]; + src_scan[0] = src_b; + src_scan[1] = src_g; + src_scan[2] = src_r; + _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); + *dest_scan = + FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], alpha_ratio); + dest_scan++; + *dest_scan = + FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], alpha_ratio); + dest_scan++; + *dest_scan = + FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio); + } else if (blend_type) { + int blended = _BLEND(blend_type, *dest_scan, src_b); + blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); + dest_scan++; + blended = _BLEND(blend_type, *dest_scan, src_g); + blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); + dest_scan++; + blended = _BLEND(blend_type, *dest_scan, src_r); + blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); + } else { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio); + } + dest_scan += 2; + } } -inline void _CompositeRow_1bppRgb2Rgb_NoBlend_RgbByteOrder(uint8_t* dest_scan, const uint8_t* src_scan, int src_left, - FX_ARGB* pPalette, int pixel_count, int DestBpp, const uint8_t* clip_scan) -{ - int reset_r, reset_g, reset_b; - int set_r, set_g, set_b; - if (pPalette) { - reset_r = FXARGB_R(pPalette[0]); - reset_g = FXARGB_G(pPalette[0]); - reset_b = FXARGB_B(pPalette[0]); - set_r = FXARGB_R(pPalette[1]); - set_g = FXARGB_G(pPalette[1]); - set_b = FXARGB_B(pPalette[1]); +void _CompositeRow_ByteMask2Rgba(uint8_t* dest_scan, + const uint8_t* src_scan, + int mask_alpha, + int src_r, + int src_g, + int src_b, + int pixel_count, + int blend_type, + const uint8_t* clip_scan, + uint8_t* dest_alpha_scan) { + for (int col = 0; col < pixel_count; col++) { + int src_alpha; + if (clip_scan) { + src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255; } else { - reset_r = reset_g = reset_b = 0; - set_r = set_g = set_b = 255; - } - for (int col = 0; col < pixel_count; col ++) { - int src_r, src_g, src_b; - if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) { - src_r = set_r; - src_g = set_g; - src_b = set_b; - } else { - src_r = reset_r; - src_g = reset_g; - src_b = reset_b; - } - if (clip_scan && clip_scan[col] < 255) { - dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, clip_scan[col]); - dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, clip_scan[col]); - dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, clip_scan[col]); - } else { - dest_scan[2] = src_b; - dest_scan[1] = src_g; - dest_scan[0] = src_r; - } - dest_scan += DestBpp; + src_alpha = mask_alpha * src_scan[col] / 255; } -} -inline void _CompositeRow_8bppRgb2Argb_NoBlend_RgbByteOrder(uint8_t* dest_scan, const uint8_t* src_scan, int width, - FX_ARGB* pPalette, const uint8_t* clip_scan) -{ - for (int col = 0; col < width; col ++) { - int src_r, src_g, src_b; - if (pPalette) { - FX_ARGB argb = pPalette[*src_scan]; - src_r = FXARGB_R(argb); - src_g = FXARGB_G(argb); - src_b = FXARGB_B(argb); - } else { - src_r = src_g = src_b = *src_scan; - } - if (clip_scan == NULL || clip_scan[col] == 255) { - dest_scan[2] = FX_GAMMA(src_b); - dest_scan[1] = FX_GAMMA(src_g); - dest_scan[0] = FX_GAMMA(src_r); - dest_scan[3] = 255; - src_scan ++; - dest_scan += 4; - continue; - } - int src_alpha = clip_scan[col]; - if (src_alpha == 0) { - dest_scan += 4; - src_scan ++; - continue; - } - int back_alpha = dest_scan[3]; - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - dest_scan[3] = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], FX_GAMMA(src_b), alpha_ratio); - dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], FX_GAMMA(src_g), alpha_ratio); - dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], FX_GAMMA(src_r), alpha_ratio); - dest_scan += 4; - src_scan ++; + uint8_t back_alpha = *dest_alpha_scan; + if (back_alpha == 0) { + *dest_scan++ = src_b; + *dest_scan++ = src_g; + *dest_scan++ = src_r; + *dest_alpha_scan++ = src_alpha; + continue; } + if (src_alpha == 0) { + dest_scan += 3; + dest_alpha_scan++; + continue; + } + uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; + *dest_alpha_scan++ = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + if (blend_type >= FXDIB_BLEND_NONSEPARABLE) { + int blended_colors[3]; + uint8_t src_scan[3]; + src_scan[0] = src_b; + src_scan[1] = src_g; + src_scan[2] = src_r; + _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); + *dest_scan = + FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], alpha_ratio); + dest_scan++; + *dest_scan = + FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], alpha_ratio); + dest_scan++; + *dest_scan = + FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio); + dest_scan++; + } else if (blend_type) { + int blended = _BLEND(blend_type, *dest_scan, src_b); + blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); + dest_scan++; + blended = _BLEND(blend_type, *dest_scan, src_g); + blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); + dest_scan++; + blended = _BLEND(blend_type, *dest_scan, src_r); + blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); + dest_scan++; + } else { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio); + dest_scan++; + } + } } -inline void _CompositeRow_1bppRgb2Argb_NoBlend_RgbByteOrder(uint8_t* dest_scan, const uint8_t* src_scan, int src_left, int width, - FX_ARGB* pPalette, const uint8_t* clip_scan) -{ - int reset_r, reset_g, reset_b; - int set_r, set_g, set_b; - if (pPalette) { - reset_r = FXARGB_R(pPalette[0]); - reset_g = FXARGB_G(pPalette[0]); - reset_b = FXARGB_B(pPalette[0]); - set_r = FXARGB_R(pPalette[1]); - set_g = FXARGB_G(pPalette[1]); - set_b = FXARGB_B(pPalette[1]); +void _CompositeRow_ByteMask2Rgb(uint8_t* dest_scan, + const uint8_t* src_scan, + int mask_alpha, + int src_r, + int src_g, + int src_b, + int pixel_count, + int blend_type, + int Bpp, + const uint8_t* clip_scan) { + for (int col = 0; col < pixel_count; col++) { + int src_alpha; + if (clip_scan) { + src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255; } else { - reset_r = reset_g = reset_b = 0; - set_r = set_g = set_b = 255; - } - for (int col = 0; col < width; col ++) { - int src_r, src_g, src_b; - if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) { - src_r = set_r; - src_g = set_g; - src_b = set_b; - } else { - src_r = reset_r; - src_g = reset_g; - src_b = reset_b; - } - if (clip_scan == NULL || clip_scan[col] == 255) { - dest_scan[2] = FX_GAMMA(src_b); - dest_scan[1] = FX_GAMMA(src_g); - dest_scan[0] = FX_GAMMA(src_r); - dest_scan[3] = 255; - dest_scan += 4; - continue; - } - int src_alpha = clip_scan[col]; - if (src_alpha == 0) { - dest_scan += 4; - continue; - } - int back_alpha = dest_scan[3]; - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - dest_scan[3] = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], FX_GAMMA(src_b), alpha_ratio); - dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], FX_GAMMA(src_g), alpha_ratio); - dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], FX_GAMMA(src_r), alpha_ratio); - dest_scan += 4; + src_alpha = mask_alpha * src_scan[col] / 255; } + if (src_alpha == 0) { + dest_scan += Bpp; + continue; + } + if (blend_type >= FXDIB_BLEND_NONSEPARABLE) { + int blended_colors[3]; + uint8_t src_scan[3]; + src_scan[0] = src_b; + src_scan[1] = src_g; + src_scan[2] = src_r; + _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], src_alpha); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], src_alpha); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], src_alpha); + } else if (blend_type) { + int blended = _BLEND(blend_type, *dest_scan, src_b); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha); + dest_scan++; + blended = _BLEND(blend_type, *dest_scan, src_g); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha); + dest_scan++; + blended = _BLEND(blend_type, *dest_scan, src_r); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha); + } else { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, src_alpha); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, src_alpha); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, src_alpha); + } + dest_scan += Bpp - 2; + } } -void _CompositeRow_ByteMask2Argb_RgbByteOrder(uint8_t* dest_scan, const uint8_t* src_scan, int mask_alpha, int src_r, int src_g, int src_b, int pixel_count, - int blend_type, const uint8_t* clip_scan) -{ - for (int col = 0; col < pixel_count; col ++) { - int src_alpha; - if (clip_scan) { - src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255; - } else { - src_alpha = mask_alpha * src_scan[col] / 255; - } - uint8_t back_alpha = dest_scan[3]; - if (back_alpha == 0) { - FXARGB_SETRGBORDERDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b)); - dest_scan += 4; - continue; - } - if (src_alpha == 0) { - dest_scan += 4; - continue; - } - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - dest_scan[3] = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - if (blend_type >= FXDIB_BLEND_NONSEPARABLE) { - int blended_colors[3]; - uint8_t src_scan[3]; - uint8_t dest_scan_o[3]; - src_scan[0] = src_b; - src_scan[1] = src_g; - src_scan[2] = src_r; - dest_scan_o[0] = dest_scan[2]; - dest_scan_o[1] = dest_scan[1]; - dest_scan_o[2] = dest_scan[0]; - _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors); - dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], alpha_ratio); - dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], alpha_ratio); - dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], alpha_ratio); - } else if (blend_type) { - int blended = _BLEND(blend_type, dest_scan[2], src_b); - blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha); - dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended, alpha_ratio); - blended = _BLEND(blend_type, dest_scan[1], src_g); - blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha); - dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended, alpha_ratio); - blended = _BLEND(blend_type, dest_scan[0], src_r); - blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha); - dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended, alpha_ratio); - } else { - dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, alpha_ratio); - dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, alpha_ratio); - dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, alpha_ratio); - } - dest_scan += 4; +void _CompositeRow_ByteMask2Mask(uint8_t* dest_scan, + const uint8_t* src_scan, + int mask_alpha, + int pixel_count, + const uint8_t* clip_scan) { + for (int col = 0; col < pixel_count; col++) { + int src_alpha; + if (clip_scan) { + src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255; + } else { + src_alpha = mask_alpha * src_scan[col] / 255; } + uint8_t back_alpha = *dest_scan; + if (!back_alpha) { + *dest_scan = src_alpha; + } else if (src_alpha) { + *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255; + } + dest_scan++; + } } -void _CompositeRow_ByteMask2Rgb_RgbByteOrder(uint8_t* dest_scan, const uint8_t* src_scan, int mask_alpha, int src_r, int src_g, int src_b, int pixel_count, - int blend_type, int Bpp, const uint8_t* clip_scan) -{ - for (int col = 0; col < pixel_count; col ++) { - int src_alpha; - if (clip_scan) { - src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255; - } else { - src_alpha = mask_alpha * src_scan[col] / 255; - } - if (src_alpha == 0) { - dest_scan += Bpp; - continue; - } - if (blend_type >= FXDIB_BLEND_NONSEPARABLE) { - int blended_colors[3]; - uint8_t src_scan[3]; - uint8_t dest_scan_o[3]; - src_scan[0] = src_b; - src_scan[1] = src_g; - src_scan[2] = src_r; - dest_scan_o[0] = dest_scan[2]; - dest_scan_o[1] = dest_scan[1]; - dest_scan_o[2] = dest_scan[0]; - _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors); - dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], src_alpha); - dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], src_alpha); - dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], src_alpha); - } else if (blend_type) { - int blended = _BLEND(blend_type, dest_scan[2], src_b); - dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended, src_alpha); - blended = _BLEND(blend_type, dest_scan[1], src_g); - dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended, src_alpha); - blended = _BLEND(blend_type, dest_scan[0], src_r); - dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended, src_alpha); - } else { - dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, src_alpha); - dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, src_alpha); - dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, src_alpha); - } - dest_scan += Bpp; +void _CompositeRow_ByteMask2Gray(uint8_t* dest_scan, + const uint8_t* src_scan, + int mask_alpha, + int src_gray, + int pixel_count, + const uint8_t* clip_scan) { + for (int col = 0; col < pixel_count; col++) { + int src_alpha; + if (clip_scan) { + src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255; + } else { + src_alpha = mask_alpha * src_scan[col] / 255; } + if (src_alpha) { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_gray, src_alpha); + } + dest_scan++; + } } -void _CompositeRow_BitMask2Argb_RgbByteOrder(uint8_t* dest_scan, const uint8_t* src_scan, int mask_alpha, int src_r, int src_g, int src_b, - int src_left, int pixel_count, int blend_type, const uint8_t* clip_scan) -{ - if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && mask_alpha == 255) { - FX_ARGB argb = FXARGB_MAKE(0xff, src_r, src_g, src_b); - for (int col = 0; col < pixel_count; col ++) { - if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) { - FXARGB_SETRGBORDERDIB(dest_scan, argb); - } - dest_scan += 4; - } - return; +void _CompositeRow_ByteMask2Graya(uint8_t* dest_scan, + const uint8_t* src_scan, + int mask_alpha, + int src_gray, + int pixel_count, + const uint8_t* clip_scan, + uint8_t* dest_alpha_scan) { + for (int col = 0; col < pixel_count; col++) { + int src_alpha; + if (clip_scan) { + src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255; + } else { + src_alpha = mask_alpha * src_scan[col] / 255; } - for (int col = 0; col < pixel_count; col ++) { - if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) { - dest_scan += 4; - continue; - } - int src_alpha; - if (clip_scan) { - src_alpha = mask_alpha * clip_scan[col] / 255; - } else { - src_alpha = mask_alpha; - } - uint8_t back_alpha = dest_scan[3]; - if (back_alpha == 0) { - FXARGB_SETRGBORDERDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b)); - dest_scan += 4; - continue; - } - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - dest_scan[3] = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - if (blend_type >= FXDIB_BLEND_NONSEPARABLE) { - int blended_colors[3]; - uint8_t src_scan[3]; - uint8_t dest_scan_o[3]; - src_scan[0] = src_b; - src_scan[1] = src_g; - src_scan[2] = src_r; - dest_scan_o[0] = dest_scan[2]; - dest_scan_o[1] = dest_scan[1]; - dest_scan_o[2] = dest_scan[0]; - _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors); - dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], alpha_ratio); - dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], alpha_ratio); - dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], alpha_ratio); - } else if (blend_type) { - int blended = _BLEND(blend_type, dest_scan[2], src_b); - blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha); - dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended, alpha_ratio); - blended = _BLEND(blend_type, dest_scan[1], src_g); - blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha); - dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended, alpha_ratio); - blended = _BLEND(blend_type, dest_scan[0], src_r); - blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha); - dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended, alpha_ratio); - } else { - dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, alpha_ratio); - dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, alpha_ratio); - dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, alpha_ratio); - } - dest_scan += 4; + uint8_t back_alpha = *dest_alpha_scan; + if (back_alpha == 0) { + *dest_scan++ = src_gray; + *dest_alpha_scan++ = src_alpha; + continue; } + if (src_alpha == 0) { + dest_scan++; + dest_alpha_scan++; + continue; + } + uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; + *dest_alpha_scan++ = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_gray, alpha_ratio); + dest_scan++; + } } -void _CompositeRow_BitMask2Rgb_RgbByteOrder(uint8_t* dest_scan, const uint8_t* src_scan, int mask_alpha, int src_r, int src_g, int src_b, - int src_left, int pixel_count, int blend_type, int Bpp, const uint8_t* clip_scan) -{ - if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && mask_alpha == 255) { - for (int col = 0; col < pixel_count; col ++) { - if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) { - dest_scan[2] = src_b; - dest_scan[1] = src_g; - dest_scan[0] = src_r; - } - dest_scan += Bpp; - } - return; +void _CompositeRow_BitMask2Argb(uint8_t* dest_scan, + const uint8_t* src_scan, + int mask_alpha, + int src_r, + int src_g, + int src_b, + int src_left, + int pixel_count, + int blend_type, + const uint8_t* clip_scan) { + if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && + mask_alpha == 255) { + FX_ARGB argb = FXARGB_MAKE(0xff, src_r, src_g, src_b); + for (int col = 0; col < pixel_count; col++) { + if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) { + FXARGB_SETDIB(dest_scan, argb); + } + dest_scan += 4; + } + return; + } + for (int col = 0; col < pixel_count; col++) { + if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) { + dest_scan += 4; + continue; + } + int src_alpha; + if (clip_scan) { + src_alpha = mask_alpha * clip_scan[col] / 255; + } else { + src_alpha = mask_alpha; + } + uint8_t back_alpha = dest_scan[3]; + if (back_alpha == 0) { + FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b)); + dest_scan += 4; + continue; + } + uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; + dest_scan[3] = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + if (blend_type >= FXDIB_BLEND_NONSEPARABLE) { + int blended_colors[3]; + uint8_t src_scan[3]; + src_scan[0] = src_b; + src_scan[1] = src_g; + src_scan[2] = src_r; + _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); + *dest_scan = + FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], alpha_ratio); + dest_scan++; + *dest_scan = + FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], alpha_ratio); + dest_scan++; + *dest_scan = + FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio); + } else if (blend_type) { + int blended = _BLEND(blend_type, *dest_scan, src_b); + blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); + dest_scan++; + blended = _BLEND(blend_type, *dest_scan, src_g); + blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); + dest_scan++; + blended = _BLEND(blend_type, *dest_scan, src_r); + blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); + } else { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio); + } + dest_scan += 2; + } +} +void _CompositeRow_BitMask2Rgba(uint8_t* dest_scan, + const uint8_t* src_scan, + int mask_alpha, + int src_r, + int src_g, + int src_b, + int src_left, + int pixel_count, + int blend_type, + const uint8_t* clip_scan, + uint8_t* dest_alpha_scan) { + if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && + mask_alpha == 255) { + for (int col = 0; col < pixel_count; col++) { + if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) { + dest_scan[0] = src_b; + dest_scan[1] = src_g; + dest_scan[2] = src_r; + *dest_alpha_scan = mask_alpha; + } + dest_scan += 3; + dest_alpha_scan++; + } + return; + } + for (int col = 0; col < pixel_count; col++) { + if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) { + dest_scan += 3; + dest_alpha_scan++; + continue; + } + int src_alpha; + if (clip_scan) { + src_alpha = mask_alpha * clip_scan[col] / 255; + } else { + src_alpha = mask_alpha; + } + uint8_t back_alpha = dest_scan[3]; + if (back_alpha == 0) { + *dest_scan++ = src_b; + *dest_scan++ = src_g; + *dest_scan++ = src_r; + *dest_alpha_scan++ = mask_alpha; + continue; + } + uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; + *dest_alpha_scan++ = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + if (blend_type >= FXDIB_BLEND_NONSEPARABLE) { + int blended_colors[3]; + uint8_t src_scan[3]; + src_scan[0] = src_b; + src_scan[1] = src_g; + src_scan[2] = src_r; + _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); + *dest_scan = + FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], alpha_ratio); + dest_scan++; + *dest_scan = + FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], alpha_ratio); + dest_scan++; + *dest_scan = + FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio); + dest_scan++; + } else if (blend_type) { + int blended = _BLEND(blend_type, *dest_scan, src_b); + blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); + dest_scan++; + blended = _BLEND(blend_type, *dest_scan, src_g); + blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); + dest_scan++; + blended = _BLEND(blend_type, *dest_scan, src_r); + blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio); + dest_scan++; + } else { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio); + dest_scan++; + } + } +} +void _CompositeRow_BitMask2Rgb(uint8_t* dest_scan, + const uint8_t* src_scan, + int mask_alpha, + int src_r, + int src_g, + int src_b, + int src_left, + int pixel_count, + int blend_type, + int Bpp, + const uint8_t* clip_scan) { + if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && + mask_alpha == 255) { + for (int col = 0; col < pixel_count; col++) { + if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) { + dest_scan[2] = src_r; + dest_scan[1] = src_g; + dest_scan[0] = src_b; + } + dest_scan += Bpp; + } + return; + } + for (int col = 0; col < pixel_count; col++) { + if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) { + dest_scan += Bpp; + continue; + } + int src_alpha; + if (clip_scan) { + src_alpha = mask_alpha * clip_scan[col] / 255; + } else { + src_alpha = mask_alpha; + } + if (src_alpha == 0) { + dest_scan += Bpp; + continue; + } + if (blend_type >= FXDIB_BLEND_NONSEPARABLE) { + int blended_colors[3]; + uint8_t src_scan[3]; + src_scan[0] = src_b; + src_scan[1] = src_g; + src_scan[2] = src_r; + _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], src_alpha); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], src_alpha); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], src_alpha); + } else if (blend_type) { + int blended = _BLEND(blend_type, *dest_scan, src_b); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha); + dest_scan++; + blended = _BLEND(blend_type, *dest_scan, src_g); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha); + dest_scan++; + blended = _BLEND(blend_type, *dest_scan, src_r); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha); + } else { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, src_alpha); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, src_alpha); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, src_alpha); + } + dest_scan += Bpp - 2; + } +} +void _CompositeRow_BitMask2Mask(uint8_t* dest_scan, + const uint8_t* src_scan, + int mask_alpha, + int src_left, + int pixel_count, + const uint8_t* clip_scan) { + for (int col = 0; col < pixel_count; col++) { + if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) { + dest_scan++; + continue; + } + int src_alpha; + if (clip_scan) { + src_alpha = mask_alpha * clip_scan[col] / 255; + } else { + src_alpha = mask_alpha; } - for (int col = 0; col < pixel_count; col ++) { - if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) { - dest_scan += Bpp; - continue; - } - int src_alpha; - if (clip_scan) { - src_alpha = mask_alpha * clip_scan[col] / 255; - } else { - src_alpha = mask_alpha; - } - if (src_alpha == 0) { - dest_scan += Bpp; - continue; - } - if (blend_type >= FXDIB_BLEND_NONSEPARABLE) { - int blended_colors[3]; - uint8_t src_scan[3]; - uint8_t dest_scan_o[3]; - src_scan[0] = src_b; - src_scan[1] = src_g; - src_scan[2] = src_r; - dest_scan_o[0] = dest_scan[2]; - dest_scan_o[1] = dest_scan[1]; - dest_scan_o[2] = dest_scan[0]; - _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors); - dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], src_alpha); - dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], src_alpha); - dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], src_alpha); - } else if (blend_type) { - int back_color = FX_GAMMA(dest_scan[2]); - int blended = _BLEND(blend_type, back_color, src_b); - dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha)); - back_color = FX_GAMMA(dest_scan[1]); - blended = _BLEND(blend_type, back_color, src_g); - dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha)); - back_color = FX_GAMMA(dest_scan[0]); - blended = _BLEND(blend_type, back_color, src_r); - dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha)); - } else { - dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), src_b, src_alpha)); - dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), src_g, src_alpha)); - dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), src_r, src_alpha)); - } - dest_scan += Bpp; + uint8_t back_alpha = *dest_scan; + if (!back_alpha) { + *dest_scan = src_alpha; + } else if (src_alpha) { + *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255; } + dest_scan++; + } } -inline FX_BOOL _ScanlineCompositor_InitSourceMask(FXDIB_Format dest_format, int alpha_flag, FX_DWORD mask_color, int& mask_alpha, - int& mask_red, int& mask_green, int& mask_blue, int& mask_black, - void* icc_module, void* pIccTransform) -{ - ICodec_IccModule* pIccModule = (ICodec_IccModule*)icc_module; - if (alpha_flag >> 8) { - mask_alpha = alpha_flag & 0xff; - mask_red = FXSYS_GetCValue(mask_color); - mask_green = FXSYS_GetMValue(mask_color); - mask_blue = FXSYS_GetYValue(mask_color); - mask_black = FXSYS_GetKValue(mask_color); +void _CompositeRow_BitMask2Gray(uint8_t* dest_scan, + const uint8_t* src_scan, + int mask_alpha, + int src_gray, + int src_left, + int pixel_count, + const uint8_t* clip_scan) { + for (int col = 0; col < pixel_count; col++) { + if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) { + dest_scan++; + continue; + } + int src_alpha; + if (clip_scan) { + src_alpha = mask_alpha * clip_scan[col] / 255; } else { - mask_alpha = FXARGB_A(mask_color); - mask_red = FXARGB_R(mask_color); - mask_green = FXARGB_G(mask_color); - mask_blue = FXARGB_B(mask_color); + src_alpha = mask_alpha; } - if (dest_format == FXDIB_8bppMask) { - return TRUE; + if (src_alpha) { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_gray, src_alpha); } - if ((dest_format & 0xff) == 8) { - if (pIccTransform) { - mask_color = (alpha_flag >> 8) ? FXCMYK_TODIB(mask_color) : FXARGB_TODIB(mask_color); - uint8_t* gray_p = (uint8_t*)&mask_color; - pIccModule->TranslateScanline(pIccTransform, gray_p, gray_p, 1); - mask_red = dest_format & 0x0400 ? FX_CCOLOR(gray_p[0]) : gray_p[0]; - } else { - if (alpha_flag >> 8) { - uint8_t r, g, b; - AdobeCMYK_to_sRGB1(mask_red, mask_green, mask_blue, mask_black, - r, g, b); - mask_red = FXRGB2GRAY(r, g, b); - } else { - mask_red = FXRGB2GRAY(mask_red, mask_green, mask_blue); - } - if (dest_format & 0x0400) { - mask_red = FX_CCOLOR(mask_red); - } - } + dest_scan++; + } +} +void _CompositeRow_BitMask2Graya(uint8_t* dest_scan, + const uint8_t* src_scan, + int mask_alpha, + int src_gray, + int src_left, + int pixel_count, + const uint8_t* clip_scan, + uint8_t* dest_alpha_scan) { + for (int col = 0; col < pixel_count; col++) { + if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) { + dest_scan++; + dest_alpha_scan++; + continue; + } + int src_alpha; + if (clip_scan) { + src_alpha = mask_alpha * clip_scan[col] / 255; } else { - uint8_t* mask_color_p = (uint8_t*)&mask_color; - mask_color = (alpha_flag >> 8) ? FXCMYK_TODIB(mask_color) : FXARGB_TODIB(mask_color); - if (pIccTransform) { - pIccModule->TranslateScanline(pIccTransform, mask_color_p, mask_color_p, 1); - mask_red = mask_color_p[2]; - mask_green = mask_color_p[1]; - mask_blue = mask_color_p[0]; - } else if (alpha_flag >> 8) { - AdobeCMYK_to_sRGB1(mask_color_p[0], mask_color_p[1], mask_color_p[2], mask_color_p[3], - mask_color_p[2], mask_color_p[1], mask_color_p[0]); - mask_red = mask_color_p[2]; - mask_green = mask_color_p[1]; - mask_blue = mask_color_p[0]; - } + src_alpha = mask_alpha; } - return TRUE; + uint8_t back_alpha = *dest_alpha_scan; + if (back_alpha == 0) { + *dest_scan++ = src_gray; + *dest_alpha_scan++ = src_alpha; + continue; + } + if (src_alpha == 0) { + dest_scan++; + dest_alpha_scan++; + continue; + } + uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; + *dest_alpha_scan++ = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_gray, alpha_ratio); + dest_scan++; + } } -inline void _ScanlineCompositor_InitSourcePalette(FXDIB_Format src_format, FXDIB_Format dest_format, - FX_DWORD*& pDestPalette, FX_DWORD* pSrcPalette, - void* icc_module, void* pIccTransform) -{ - ICodec_IccModule* pIccModule = (ICodec_IccModule*)icc_module; - FX_BOOL isSrcCmyk = src_format & 0x0400 ? TRUE : FALSE; - FX_BOOL isDstCmyk = dest_format & 0x0400 ? TRUE : FALSE; - pDestPalette = NULL; - if (pIccTransform) { - if (pSrcPalette) { - if ((dest_format & 0xff) == 8) { - int pal_count = 1 << (src_format & 0xff); - uint8_t* gray_pal = FX_Alloc(uint8_t, pal_count); - pDestPalette = (FX_DWORD*)gray_pal; - for (int i = 0; i < pal_count; i ++) { - FX_DWORD color = isSrcCmyk ? FXCMYK_TODIB(pSrcPalette[i]) : FXARGB_TODIB(pSrcPalette[i]); - pIccModule->TranslateScanline(pIccTransform, gray_pal, (const uint8_t*)&color, 1); - gray_pal ++; - } - } else { - int palsize = 1 << (src_format & 0xff); - pDestPalette = FX_Alloc(FX_DWORD, palsize); - for (int i = 0; i < palsize; i ++) { - FX_DWORD color = isSrcCmyk ? FXCMYK_TODIB(pSrcPalette[i]) : FXARGB_TODIB(pSrcPalette[i]); - pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&color, (const uint8_t*)&color, 1); - pDestPalette[i] = isDstCmyk ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); - } - } - } else { - int pal_count = 1 << (src_format & 0xff); - uint8_t* gray_pal = FX_Alloc(uint8_t, pal_count); - if (pal_count == 2) { - gray_pal[0] = 0; - gray_pal[1] = 255; - } else { - for (int i = 0; i < pal_count; i++) { - gray_pal[i] = i; - } - } - if ((dest_format & 0xff) == 8) { - pIccModule->TranslateScanline(pIccTransform, gray_pal, gray_pal, pal_count); - pDestPalette = (FX_DWORD*)gray_pal; - } else { - pDestPalette = FX_Alloc(FX_DWORD, pal_count); - for (int i = 0; i < pal_count; i ++) { - pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&pDestPalette[i], &gray_pal[i], 1); - pDestPalette[i] = isDstCmyk ? FXCMYK_TODIB(pDestPalette[i]) : FXARGB_TODIB(pDestPalette[i]); - } - FX_Free(gray_pal); - } - } +void _CompositeRow_Argb2Argb_RgbByteOrder(uint8_t* dest_scan, + const uint8_t* src_scan, + int pixel_count, + int blend_type, + const uint8_t* clip_scan) { + int blended_colors[3]; + FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; + for (int col = 0; col < pixel_count; col++) { + uint8_t back_alpha = dest_scan[3]; + if (back_alpha == 0) { + if (clip_scan) { + int src_alpha = clip_scan[col] * src_scan[3] / 255; + dest_scan[3] = src_alpha; + dest_scan[0] = src_scan[2]; + dest_scan[1] = src_scan[1]; + dest_scan[2] = src_scan[0]; + } else { + FXARGB_RGBORDERCOPY(dest_scan, src_scan); + } + dest_scan += 4; + src_scan += 4; + continue; + } + uint8_t src_alpha; + if (clip_scan == NULL) { + src_alpha = src_scan[3]; } else { - if (pSrcPalette) { - if ((dest_format & 0xff) == 8) { - int pal_count = 1 << (src_format & 0xff); - uint8_t* gray_pal = FX_Alloc(uint8_t, pal_count); - pDestPalette = (FX_DWORD*)gray_pal; - if (isSrcCmyk) { - for (int i = 0; i < pal_count; i ++) { - FX_CMYK cmyk = pSrcPalette[i]; - uint8_t r, g, b; - AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk), FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk), - r, g, b); - *gray_pal ++ = FXRGB2GRAY(r, g, b); - } - } else - for (int i = 0; i < pal_count; i ++) { - FX_ARGB argb = pSrcPalette[i]; - *gray_pal ++ = FXRGB2GRAY(FXARGB_R(argb), FXARGB_G(argb), FXARGB_B(argb)); - } - } else { - int palsize = 1 << (src_format & 0xff); - pDestPalette = FX_Alloc(FX_DWORD, palsize); - if (isDstCmyk == isSrcCmyk) { - FXSYS_memcpy(pDestPalette, pSrcPalette, palsize * sizeof(FX_DWORD)); - } else { - for (int i = 0; i < palsize; i ++) { - FX_CMYK cmyk = pSrcPalette[i]; - uint8_t r, g, b; - AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk), FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk), - r, g, b); - pDestPalette[i] = FXARGB_MAKE(0xff, r, g, b); - } - } - } - } else { - if ((dest_format & 0xff) == 8) { - int pal_count = 1 << (src_format & 0xff); - uint8_t* gray_pal = FX_Alloc(uint8_t, pal_count); - if (pal_count == 2) { - gray_pal[0] = 0; - gray_pal[1] = 255; - } else { - for (int i = 0; i < pal_count; i++) { - gray_pal[i] = i; - } - } - pDestPalette = (FX_DWORD*)gray_pal; - } else { - int palsize = 1 << (src_format & 0xff); - pDestPalette = FX_Alloc(FX_DWORD, palsize); - if (palsize == 2) { - pDestPalette[0] = isSrcCmyk ? 255 : 0xff000000; - pDestPalette[1] = isSrcCmyk ? 0 : 0xffffffff; - } else { - for (int i = 0; i < palsize; i++) { - pDestPalette[i] = isSrcCmyk ? FX_CCOLOR(i) : (i * 0x10101); - } - } - if (isSrcCmyk != isDstCmyk) { - for (int i = 0; i < palsize; i ++) { - FX_CMYK cmyk = pDestPalette[i]; - uint8_t r, g, b; - AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk), FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk), - r, g, b); - pDestPalette[i] = FXARGB_MAKE(0xff, r, g, b); - } - } - } - } + src_alpha = clip_scan[col] * src_scan[3] / 255; } + if (src_alpha == 0) { + dest_scan += 4; + src_scan += 4; + continue; + } + uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; + dest_scan[3] = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + if (bNonseparableBlend) { + uint8_t dest_scan_o[3]; + dest_scan_o[0] = dest_scan[2]; + dest_scan_o[1] = dest_scan[1]; + dest_scan_o[2] = dest_scan[0]; + _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors); + } + for (int color = 0; color < 3; color++) { + int index = 2 - color; + if (blend_type) { + int blended = bNonseparableBlend + ? blended_colors[color] + : _BLEND(blend_type, dest_scan[index], *src_scan); + blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha); + dest_scan[index] = + FXDIB_ALPHA_MERGE(dest_scan[index], blended, alpha_ratio); + } else { + dest_scan[index] = + FXDIB_ALPHA_MERGE(dest_scan[index], *src_scan, alpha_ratio); + } + src_scan++; + } + dest_scan += 4; + src_scan++; + } } -CFX_ScanlineCompositor::CFX_ScanlineCompositor() -{ - m_pSrcPalette = NULL; - m_pCacheScanline = NULL; - m_CacheSize = 0; - m_bRgbByteOrder = FALSE; - m_BlendType = FXDIB_BLEND_NORMAL; +void _CompositeRow_Rgb2Argb_Blend_NoClip_RgbByteOrder(uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + int blend_type, + int src_Bpp) { + int blended_colors[3]; + FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; + int src_gap = src_Bpp - 3; + for (int col = 0; col < width; col++) { + uint8_t back_alpha = dest_scan[3]; + if (back_alpha == 0) { + if (src_Bpp == 4) { + FXARGB_SETRGBORDERDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan)); + } else { + FXARGB_SETRGBORDERDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[2], + src_scan[1], src_scan[0])); + } + dest_scan += 4; + src_scan += src_Bpp; + continue; + } + dest_scan[3] = 0xff; + if (bNonseparableBlend) { + uint8_t dest_scan_o[3]; + dest_scan_o[0] = dest_scan[2]; + dest_scan_o[1] = dest_scan[1]; + dest_scan_o[2] = dest_scan[0]; + _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors); + } + for (int color = 0; color < 3; color++) { + int index = 2 - color; + int src_color = FX_GAMMA(*src_scan); + int blended = bNonseparableBlend + ? blended_colors[color] + : _BLEND(blend_type, dest_scan[index], src_color); + dest_scan[index] = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha); + src_scan++; + } + dest_scan += 4; + src_scan += src_gap; + } } -CFX_ScanlineCompositor::~CFX_ScanlineCompositor() -{ - if (m_pSrcPalette) { - FX_Free(m_pSrcPalette); +inline void _CompositeRow_Argb2Rgb_Blend_RgbByteOrder( + uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + int blend_type, + int dest_Bpp, + const uint8_t* clip_scan) { + int blended_colors[3]; + FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; + for (int col = 0; col < width; col++) { + uint8_t src_alpha; + if (clip_scan) { + src_alpha = src_scan[3] * (*clip_scan++) / 255; + } else { + src_alpha = src_scan[3]; } - if (m_pCacheScanline) { - FX_Free(m_pCacheScanline); + if (src_alpha == 0) { + dest_scan += dest_Bpp; + src_scan += 4; + continue; + } + if (bNonseparableBlend) { + uint8_t dest_scan_o[3]; + dest_scan_o[0] = dest_scan[2]; + dest_scan_o[1] = dest_scan[1]; + dest_scan_o[2] = dest_scan[0]; + _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors); + } + for (int color = 0; color < 3; color++) { + int index = 2 - color; + int back_color = FX_GAMMA(dest_scan[index]); + int blended = bNonseparableBlend + ? blended_colors[color] + : _BLEND(blend_type, back_color, *src_scan); + dest_scan[index] = + FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha)); + src_scan++; + } + dest_scan += dest_Bpp; + src_scan++; + } +} +inline void _CompositeRow_Rgb2Argb_NoBlend_NoClip_RgbByteOrder( + uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + int src_Bpp) { + for (int col = 0; col < width; col++) { + if (src_Bpp == 4) { + FXARGB_SETRGBORDERDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan)); + } else { + FXARGB_SETRGBORDERDIB( + dest_scan, FXARGB_MAKE(0xff, src_scan[2], src_scan[1], src_scan[0])); } + dest_scan += 4; + src_scan += src_Bpp; + } } -FX_BOOL CFX_ScanlineCompositor::Init(FXDIB_Format dest_format, FXDIB_Format src_format, int32_t width, FX_DWORD* pSrcPalette, - FX_DWORD mask_color, int blend_type, FX_BOOL bClip, FX_BOOL bRgbByteOrder, int alpha_flag, void* pIccTransform) -{ - m_SrcFormat = src_format; - m_DestFormat = dest_format; - m_BlendType = blend_type; - m_bRgbByteOrder = bRgbByteOrder; - ICodec_IccModule* pIccModule = NULL; - if (CFX_GEModule::Get()->GetCodecModule()) { - pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - } - if (pIccModule == NULL) { - pIccTransform = NULL; - } - m_pIccTransform = pIccTransform; - if ((dest_format & 0xff) == 1) { - return FALSE; - } - if (m_SrcFormat == FXDIB_1bppMask || m_SrcFormat == FXDIB_8bppMask) { - return _ScanlineCompositor_InitSourceMask(dest_format, alpha_flag, mask_color, - m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue, m_MaskBlack, - pIccModule, pIccTransform); - } - if (pIccTransform == NULL && (~src_format & 0x0400) && (dest_format & 0x0400)) { - return FALSE; - } - if ((m_SrcFormat & 0xff) <= 8) { - if (dest_format == FXDIB_8bppMask) { - return TRUE; - } - _ScanlineCompositor_InitSourcePalette(src_format, dest_format, m_pSrcPalette, pSrcPalette, - pIccModule, pIccTransform); - m_Transparency = (dest_format == FXDIB_Argb ? 1 : 0) - + (dest_format & 0x0200 ? 2 : 0) - + (dest_format & 0x0400 ? 4 : 0) - + ((src_format & 0xff) == 1 ? 8 : 0); - return TRUE; - } - m_Transparency = (src_format & 0x0200 ? 0 : 1) - + (dest_format & 0x0200 ? 0 : 2) - + (blend_type == FXDIB_BLEND_NORMAL ? 4 : 0) - + (bClip ? 8 : 0) - + (src_format & 0x0400 ? 16 : 0) - + (dest_format & 0x0400 ? 32 : 0) - + (pIccTransform ? 64 : 0); - return TRUE; +inline void _CompositeRow_Rgb2Rgb_Blend_NoClip_RgbByteOrder( + uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + int blend_type, + int dest_Bpp, + int src_Bpp) { + int blended_colors[3]; + FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; + int src_gap = src_Bpp - 3; + for (int col = 0; col < width; col++) { + if (bNonseparableBlend) { + uint8_t dest_scan_o[3]; + dest_scan_o[0] = dest_scan[2]; + dest_scan_o[1] = dest_scan[1]; + dest_scan_o[2] = dest_scan[0]; + _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors); + } + for (int color = 0; color < 3; color++) { + int index = 2 - color; + int back_color = FX_GAMMA(dest_scan[index]); + int src_color = FX_GAMMA(*src_scan); + int blended = bNonseparableBlend + ? blended_colors[color] + : _BLEND(blend_type, back_color, src_color); + dest_scan[index] = FX_GAMMA_INVERSE(blended); + src_scan++; + } + dest_scan += dest_Bpp; + src_scan += src_gap; + } } -void CFX_ScanlineCompositor::CompositeRgbBitmapLine(uint8_t* dest_scan, const uint8_t* src_scan, int width, const uint8_t* clip_scan, - const uint8_t* src_extra_alpha, uint8_t* dst_extra_alpha) -{ - int src_Bpp = (m_SrcFormat & 0xff) >> 3; - int dest_Bpp = (m_DestFormat & 0xff) >> 3; - if (m_bRgbByteOrder) { - switch (m_Transparency) { - case 0: - case 4: - case 8: - case 12: - _CompositeRow_Argb2Argb_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, clip_scan); - break; - case 1: - _CompositeRow_Rgb2Argb_Blend_NoClip_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, src_Bpp); - break; - case 2: - case 10: - _CompositeRow_Argb2Rgb_Blend_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, dest_Bpp, clip_scan); - break; - case 3: - _CompositeRow_Rgb2Rgb_Blend_NoClip_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp); - break; - case 5: - _CompositeRow_Rgb2Argb_NoBlend_NoClip_RgbByteOrder(dest_scan, src_scan, width, src_Bpp); - break; - case 6: - case 14: - _CompositeRow_Argb2Rgb_NoBlend_RgbByteOrder(dest_scan, src_scan, width, dest_Bpp, clip_scan); - break; - case 7: - _CompositeRow_Rgb2Rgb_NoBlend_NoClip_RgbByteOrder(dest_scan, src_scan, width, dest_Bpp, src_Bpp); - break; - case 9: - _CompositeRow_Rgb2Argb_Blend_Clip_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, src_Bpp, clip_scan); - break; - case 11: - _CompositeRow_Rgb2Rgb_Blend_Clip_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp, clip_scan); - break; - case 13: - _CompositeRow_Rgb2Argb_NoBlend_Clip_RgbByteOrder(dest_scan, src_scan, width, src_Bpp, clip_scan); - break; - case 15: - _CompositeRow_Rgb2Rgb_NoBlend_Clip_RgbByteOrder(dest_scan, src_scan, width, dest_Bpp, src_Bpp, clip_scan); - break; - } - return; - } - if (m_DestFormat == FXDIB_8bppMask) { - if (m_SrcFormat & 0x0200) { - if (m_SrcFormat == FXDIB_Argb) { - _CompositeRow_Argb2Mask(dest_scan, src_scan, width, clip_scan); - } else { - _CompositeRow_Rgba2Mask(dest_scan, src_extra_alpha, width, clip_scan); - } - } else { - _CompositeRow_Rgb2Mask(dest_scan, src_scan, width, clip_scan); - } - } else if ((m_DestFormat & 0xff) == 8) { - if (m_DestFormat & 0x0400) { - for (int i = 0; i < width; i ++) { - *dest_scan = ~*dest_scan; - dest_scan++; - } - } - if (m_SrcFormat & 0x0200) { - if (m_DestFormat & 0x0200) { - _CompositeRow_Argb2Graya(dest_scan, src_scan, width, m_BlendType, clip_scan, src_extra_alpha, dst_extra_alpha, m_pIccTransform); - } else { - _CompositeRow_Argb2Gray(dest_scan, src_scan, width, m_BlendType, clip_scan, src_extra_alpha, m_pIccTransform); - } - } else { - if (m_DestFormat & 0x0200) { - _CompositeRow_Rgb2Graya(dest_scan, src_scan, src_Bpp, width, m_BlendType, clip_scan, dst_extra_alpha, m_pIccTransform); - } else { - _CompositeRow_Rgb2Gray(dest_scan, src_scan, src_Bpp, width, m_BlendType, clip_scan, m_pIccTransform); - } - } - if (m_DestFormat & 0x0400) { - for (int i = 0; i < width; i ++) { - *dest_scan = ~*dest_scan; - dest_scan++; - } - } +inline void _CompositeRow_Argb2Rgb_NoBlend_RgbByteOrder( + uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + int dest_Bpp, + const uint8_t* clip_scan) { + for (int col = 0; col < width; col++) { + uint8_t src_alpha; + if (clip_scan) { + src_alpha = src_scan[3] * (*clip_scan++) / 255; } else { - int dest_Size = width * dest_Bpp + 4; - if (dest_Size > m_CacheSize) { - m_pCacheScanline = FX_Realloc(uint8_t, m_pCacheScanline, dest_Size); - if (!m_pCacheScanline) { - return; - } - m_CacheSize = dest_Size; - } - switch (m_Transparency) { - case 0: - case 4: - case 8: - case 4+8: { - _CompositeRow_Argb2Argb(dest_scan, src_scan, width, m_BlendType, clip_scan, - dst_extra_alpha, src_extra_alpha); - } - break; - case 64: - case 4+64: - case 8+64: - case 4+8+64: { - _CompositeRow_Argb2Argb_Transform(dest_scan, src_scan, width, m_BlendType, clip_scan, - dst_extra_alpha, src_extra_alpha, m_pCacheScanline, m_pIccTransform); - } - break; - case 1: - _CompositeRow_Rgb2Argb_Blend_NoClip(dest_scan, src_scan, width, m_BlendType, src_Bpp, - dst_extra_alpha); - break; - case 1+64: - _CompositeRow_Rgb2Argb_Blend_NoClip_Transform(dest_scan, src_scan, width, m_BlendType, src_Bpp, - dst_extra_alpha, m_pCacheScanline, m_pIccTransform); - break; - case 1+8: - _CompositeRow_Rgb2Argb_Blend_Clip(dest_scan, src_scan, width, m_BlendType, src_Bpp, clip_scan, - dst_extra_alpha); - break; - case 1+8+64: - _CompositeRow_Rgb2Argb_Blend_Clip_Transform(dest_scan, src_scan, width, m_BlendType, src_Bpp, clip_scan, - dst_extra_alpha, m_pCacheScanline, m_pIccTransform); - break; - case 1+4: - _CompositeRow_Rgb2Argb_NoBlend_NoClip(dest_scan, src_scan, width, src_Bpp, - dst_extra_alpha); - break; - case 1+4+64: - _CompositeRow_Rgb2Argb_NoBlend_NoClip_Transform(dest_scan, src_scan, width, src_Bpp, - dst_extra_alpha, m_pCacheScanline, m_pIccTransform); - break; - case 1+4+8: - _CompositeRow_Rgb2Argb_NoBlend_Clip(dest_scan, src_scan, width, src_Bpp, clip_scan, - dst_extra_alpha); - break; - case 1+4+8+64: - _CompositeRow_Rgb2Argb_NoBlend_Clip_Transform(dest_scan, src_scan, width, src_Bpp, clip_scan, - dst_extra_alpha, m_pCacheScanline, m_pIccTransform); - break; - case 2: - case 2+8: - _CompositeRow_Argb2Rgb_Blend(dest_scan, src_scan, width, m_BlendType, dest_Bpp, clip_scan, - src_extra_alpha); - break; - case 2+64: - case 2+8+64: - _CompositeRow_Argb2Rgb_Blend_Transform(dest_scan, src_scan, width, m_BlendType, dest_Bpp, clip_scan, - src_extra_alpha, m_pCacheScanline, m_pIccTransform); - break; - case 2+4: - case 2+4+8: - _CompositeRow_Argb2Rgb_NoBlend(dest_scan, src_scan, width, dest_Bpp, clip_scan, - src_extra_alpha); - break; - case 2+4+64: - case 2+4+8+64: - _CompositeRow_Argb2Rgb_NoBlend_Transform(dest_scan, src_scan, width, dest_Bpp, clip_scan, - src_extra_alpha, m_pCacheScanline, m_pIccTransform); - break; - case 1+2: - _CompositeRow_Rgb2Rgb_Blend_NoClip(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp); - break; - case 1+2+64: - _CompositeRow_Rgb2Rgb_Blend_NoClip_Transform(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp, - m_pCacheScanline, m_pIccTransform); - break; - case 1+2+8: - _CompositeRow_Rgb2Rgb_Blend_Clip(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp, clip_scan); - break; - case 1+2+8+64: - _CompositeRow_Rgb2Rgb_Blend_Clip_Transform(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp, clip_scan, - m_pCacheScanline, m_pIccTransform); - break; - case 1+2+4: - _CompositeRow_Rgb2Rgb_NoBlend_NoClip(dest_scan, src_scan, width, dest_Bpp, src_Bpp); - break; - case 1+2+4+64: - _CompositeRow_Rgb2Rgb_NoBlend_NoClip_Transform(dest_scan, src_scan, width, dest_Bpp, src_Bpp, - m_pCacheScanline, m_pIccTransform); - break; - case 1+2+4+8: - _CompositeRow_Rgb2Rgb_NoBlend_Clip(dest_scan, src_scan, width, dest_Bpp, src_Bpp, clip_scan); - break; - case 1+2+4+8+64: - _CompositeRow_Rgb2Rgb_NoBlend_Clip_Transform(dest_scan, src_scan, width, dest_Bpp, src_Bpp, clip_scan, - m_pCacheScanline, m_pIccTransform); - break; - } + src_alpha = src_scan[3]; } -} -void CFX_ScanlineCompositor::CompositePalBitmapLine(uint8_t* dest_scan, const uint8_t* src_scan, int src_left, int width, const uint8_t* clip_scan, - const uint8_t* src_extra_alpha, uint8_t* dst_extra_alpha) -{ - if (m_bRgbByteOrder) { - if (m_SrcFormat == FXDIB_1bppRgb) { - if (m_DestFormat == FXDIB_8bppRgb) { - return; - } - if(m_DestFormat == FXDIB_Argb) { - _CompositeRow_1bppRgb2Argb_NoBlend_RgbByteOrder(dest_scan, src_scan, src_left, width, m_pSrcPalette, clip_scan); - } else { - _CompositeRow_1bppRgb2Rgb_NoBlend_RgbByteOrder(dest_scan, src_scan, src_left, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan); - } - } else { - if (m_DestFormat == FXDIB_8bppRgb) { - return; - } - if (m_DestFormat == FXDIB_Argb) { - _CompositeRow_8bppRgb2Argb_NoBlend_RgbByteOrder(dest_scan, src_scan, width, m_pSrcPalette, clip_scan); - } else { - _CompositeRow_8bppRgb2Rgb_NoBlend_RgbByteOrder(dest_scan, src_scan, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan); - } - } - return; + if (src_alpha == 255) { + dest_scan[2] = FX_GAMMA_INVERSE(*src_scan++); + dest_scan[1] = FX_GAMMA_INVERSE(*src_scan++); + dest_scan[0] = FX_GAMMA_INVERSE(*src_scan++); + dest_scan += dest_Bpp; + src_scan++; + continue; } - if (m_DestFormat == FXDIB_8bppMask) { - _CompositeRow_Rgb2Mask(dest_scan, src_scan, width, clip_scan); - return; + if (src_alpha == 0) { + dest_scan += dest_Bpp; + src_scan += 4; + continue; + } + for (int color = 0; color < 3; color++) { + int index = 2 - color; + dest_scan[index] = FX_GAMMA_INVERSE( + FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[index]), *src_scan, src_alpha)); + src_scan++; + } + dest_scan += dest_Bpp; + src_scan++; + } +} +inline void _CompositeRow_Rgb2Rgb_NoBlend_NoClip_RgbByteOrder( + uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + int dest_Bpp, + int src_Bpp) { + for (int col = 0; col < width; col++) { + dest_scan[2] = src_scan[0]; + dest_scan[1] = src_scan[1]; + dest_scan[0] = src_scan[2]; + dest_scan += dest_Bpp; + src_scan += src_Bpp; + } +} +inline void _CompositeRow_Rgb2Argb_Blend_Clip_RgbByteOrder( + uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + int blend_type, + int src_Bpp, + const uint8_t* clip_scan) { + int blended_colors[3]; + FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; + int src_gap = src_Bpp - 3; + for (int col = 0; col < width; col++) { + int src_alpha = *clip_scan++; + uint8_t back_alpha = dest_scan[3]; + if (back_alpha == 0) { + dest_scan[2] = FX_GAMMA(*src_scan++); + dest_scan[1] = FX_GAMMA(*src_scan++); + dest_scan[0] = FX_GAMMA(*src_scan++); + src_scan += src_gap; + dest_scan += 4; + continue; } - if ((m_DestFormat & 0xff) == 8) { - if (m_Transparency & 8) { - if (m_DestFormat & 0x0200) { - _CompositeRow_1bppPal2Graya(dest_scan, src_scan, src_left, (const uint8_t*)m_pSrcPalette, width, m_BlendType, clip_scan, dst_extra_alpha); - } else { - _CompositeRow_1bppPal2Gray(dest_scan, src_scan, src_left, (const uint8_t*)m_pSrcPalette, width, m_BlendType, clip_scan); - } - } else { - if (m_DestFormat & 0x0200) - _CompositeRow_8bppPal2Graya(dest_scan, src_scan, (const uint8_t*)m_pSrcPalette, width, m_BlendType, clip_scan, - dst_extra_alpha, src_extra_alpha); - else - _CompositeRow_8bppPal2Gray(dest_scan, src_scan, (const uint8_t*)m_pSrcPalette, width, m_BlendType, clip_scan, - src_extra_alpha); - } - } else { - switch (m_Transparency) { - case 1+2: - _CompositeRow_8bppRgb2Argb_NoBlend(dest_scan, src_scan, width, m_pSrcPalette, clip_scan, - src_extra_alpha); - break; - case 1+2+8: - _CompositeRow_1bppRgb2Argb_NoBlend(dest_scan, src_scan, src_left, width, m_pSrcPalette, clip_scan); - break; - case 0: - _CompositeRow_8bppRgb2Rgb_NoBlend(dest_scan, src_scan, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan, - src_extra_alpha); - break; - case 0+8: - _CompositeRow_1bppRgb2Rgb_NoBlend(dest_scan, src_scan, src_left, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan); - break; - case 0+2: - _CompositeRow_8bppRgb2Rgb_NoBlend(dest_scan, src_scan, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan, - src_extra_alpha); - break; - case 0+2+8: - _CompositeRow_1bppRgb2Rgba_NoBlend(dest_scan, src_scan, src_left, width, m_pSrcPalette, clip_scan, - dst_extra_alpha); - break; - break; - } + if (src_alpha == 0) { + dest_scan += 4; + src_scan += src_Bpp; + continue; + } + uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; + dest_scan[3] = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + if (bNonseparableBlend) { + uint8_t dest_scan_o[3]; + dest_scan_o[0] = dest_scan[2]; + dest_scan_o[1] = dest_scan[1]; + dest_scan_o[2] = dest_scan[0]; + _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors); + } + for (int color = 0; color < 3; color++) { + int index = 2 - color; + int src_color = FX_GAMMA(*src_scan); + int blended = bNonseparableBlend + ? blended_colors[color] + : _BLEND(blend_type, dest_scan[index], src_color); + blended = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha); + dest_scan[index] = + FXDIB_ALPHA_MERGE(dest_scan[index], blended, alpha_ratio); + src_scan++; + } + dest_scan += 4; + src_scan += src_gap; + } +} +inline void _CompositeRow_Rgb2Rgb_Blend_Clip_RgbByteOrder( + uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + int blend_type, + int dest_Bpp, + int src_Bpp, + const uint8_t* clip_scan) { + int blended_colors[3]; + FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE; + int src_gap = src_Bpp - 3; + for (int col = 0; col < width; col++) { + uint8_t src_alpha = *clip_scan++; + if (src_alpha == 0) { + dest_scan += dest_Bpp; + src_scan += src_Bpp; + continue; + } + if (bNonseparableBlend) { + uint8_t dest_scan_o[3]; + dest_scan_o[0] = dest_scan[2]; + dest_scan_o[1] = dest_scan[1]; + dest_scan_o[2] = dest_scan[0]; + _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors); + } + for (int color = 0; color < 3; color++) { + int index = 2 - color; + int src_color = FX_GAMMA(*src_scan); + int back_color = FX_GAMMA(dest_scan[index]); + int blended = bNonseparableBlend + ? blended_colors[color] + : _BLEND(blend_type, back_color, src_color); + dest_scan[index] = + FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha)); + src_scan++; + } + dest_scan += dest_Bpp; + src_scan += src_gap; + } +} +inline void _CompositeRow_Rgb2Argb_NoBlend_Clip_RgbByteOrder( + uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + int src_Bpp, + const uint8_t* clip_scan) { + int src_gap = src_Bpp - 3; + for (int col = 0; col < width; col++) { + int src_alpha = clip_scan[col]; + if (src_alpha == 255) { + dest_scan[2] = FX_GAMMA(*src_scan++); + dest_scan[1] = FX_GAMMA(*src_scan++); + dest_scan[0] = FX_GAMMA(*src_scan++); + dest_scan[3] = 255; + dest_scan += 4; + src_scan += src_gap; + continue; } + if (src_alpha == 0) { + dest_scan += 4; + src_scan += src_Bpp; + continue; + } + int back_alpha = dest_scan[3]; + uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; + dest_scan[3] = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + for (int color = 0; color < 3; color++) { + int index = 2 - color; + dest_scan[index] = + FXDIB_ALPHA_MERGE(dest_scan[index], FX_GAMMA(*src_scan), alpha_ratio); + src_scan++; + } + dest_scan += 4; + src_scan += src_gap; + } } -void CFX_ScanlineCompositor::CompositeByteMaskLine(uint8_t* dest_scan, const uint8_t* src_scan, int width, const uint8_t* clip_scan, - uint8_t* dst_extra_alpha) -{ - if (m_DestFormat == FXDIB_8bppMask) { - _CompositeRow_ByteMask2Mask(dest_scan, src_scan, m_MaskAlpha, width, clip_scan); - } else if ((m_DestFormat & 0xff) == 8) { - if (m_DestFormat & 0x0200) { - _CompositeRow_ByteMask2Graya(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, width, clip_scan, dst_extra_alpha); - } else { - _CompositeRow_ByteMask2Gray(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, width, clip_scan); - } - } else if (m_bRgbByteOrder) { - if (m_DestFormat == FXDIB_Argb) - _CompositeRow_ByteMask2Argb_RgbByteOrder(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue, - width, m_BlendType, clip_scan); - else - _CompositeRow_ByteMask2Rgb_RgbByteOrder(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue, - width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan); - return; - } else if (m_DestFormat == FXDIB_Argb) - _CompositeRow_ByteMask2Argb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue, - width, m_BlendType, clip_scan); - else if (m_DestFormat == FXDIB_Rgb || m_DestFormat == FXDIB_Rgb32) - _CompositeRow_ByteMask2Rgb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue, - width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan); - else if (m_DestFormat == FXDIB_Rgba) - _CompositeRow_ByteMask2Rgba(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue, - width, m_BlendType, clip_scan, dst_extra_alpha); +inline void _CompositeRow_Rgb2Rgb_NoBlend_Clip_RgbByteOrder( + uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + int dest_Bpp, + int src_Bpp, + const uint8_t* clip_scan) { + for (int col = 0; col < width; col++) { + int src_alpha = clip_scan[col]; + if (src_alpha == 255) { + dest_scan[2] = src_scan[0]; + dest_scan[1] = src_scan[1]; + dest_scan[0] = src_scan[2]; + } else if (src_alpha) { + dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE( + FX_GAMMA(dest_scan[2]), FX_GAMMA(*src_scan), src_alpha)); + src_scan++; + dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE( + FX_GAMMA(dest_scan[1]), FX_GAMMA(*src_scan), src_alpha)); + src_scan++; + dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE( + FX_GAMMA(dest_scan[0]), FX_GAMMA(*src_scan), src_alpha)); + dest_scan += dest_Bpp; + src_scan += src_Bpp - 2; + continue; + } + dest_scan += dest_Bpp; + src_scan += src_Bpp; + } } -void CFX_ScanlineCompositor::CompositeBitMaskLine(uint8_t* dest_scan, const uint8_t* src_scan, int src_left, int width, const uint8_t* clip_scan, - uint8_t* dst_extra_alpha) -{ - if (m_DestFormat == FXDIB_8bppMask) { - _CompositeRow_BitMask2Mask(dest_scan, src_scan, m_MaskAlpha, src_left, width, clip_scan); - } else if ((m_DestFormat & 0xff) == 8) { - if (m_DestFormat & 0x0200) - _CompositeRow_BitMask2Graya(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, src_left, width, clip_scan, - dst_extra_alpha); - else { - _CompositeRow_BitMask2Gray(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, src_left, width, clip_scan); - } - } else if (m_bRgbByteOrder) { - if (m_DestFormat == FXDIB_Argb) - _CompositeRow_BitMask2Argb_RgbByteOrder(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue, - src_left, width, m_BlendType, clip_scan); - else - _CompositeRow_BitMask2Rgb_RgbByteOrder(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue, - src_left, width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan); - return; - } else if (m_DestFormat == FXDIB_Argb) - _CompositeRow_BitMask2Argb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue, - src_left, width, m_BlendType, clip_scan); - else if (m_DestFormat == FXDIB_Rgb || m_DestFormat == FXDIB_Rgb32) - _CompositeRow_BitMask2Rgb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue, - src_left, width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan); +inline void _CompositeRow_8bppRgb2Rgb_NoBlend_RgbByteOrder( + uint8_t* dest_scan, + const uint8_t* src_scan, + FX_ARGB* pPalette, + int pixel_count, + int DestBpp, + const uint8_t* clip_scan) { + for (int col = 0; col < pixel_count; col++) { + FX_ARGB argb = pPalette ? pPalette[*src_scan] : (*src_scan) * 0x010101; + int src_r = FXARGB_R(argb); + int src_g = FXARGB_G(argb); + int src_b = FXARGB_B(argb); + if (clip_scan && clip_scan[col] < 255) { + dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, clip_scan[col]); + dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, clip_scan[col]); + dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, clip_scan[col]); + } else { + dest_scan[2] = src_b; + dest_scan[1] = src_g; + dest_scan[0] = src_r; + } + dest_scan += DestBpp; + src_scan++; + } } -FX_BOOL CFX_DIBitmap::CompositeBitmap(int dest_left, int dest_top, int width, int height, - const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, - int blend_type, const CFX_ClipRgn* pClipRgn, FX_BOOL bRgbByteOrder, void* pIccTransform) -{ - if (m_pBuffer == NULL) { - return FALSE; - } - ASSERT(!pSrcBitmap->IsAlphaMask()); - ASSERT(m_bpp >= 8); - if (pSrcBitmap->IsAlphaMask() || m_bpp < 8) { - return FALSE; - } - GetOverlapRect(dest_left, dest_top, width, height, pSrcBitmap->GetWidth(), pSrcBitmap->GetHeight(), - src_left, src_top, pClipRgn); - if (width == 0 || height == 0) { - return TRUE; - } - const CFX_DIBitmap* pClipMask = NULL; - FX_RECT clip_box; - if (pClipRgn && pClipRgn->GetType() != CFX_ClipRgn::RectI) { - ASSERT(pClipRgn->GetType() == CFX_ClipRgn::MaskF); - pClipMask = pClipRgn->GetMask(); - clip_box = pClipRgn->GetBox(); - } - CFX_ScanlineCompositor compositor; - if (!compositor.Init(GetFormat(), pSrcBitmap->GetFormat(), width, pSrcBitmap->GetPalette(), 0, blend_type, - pClipMask != NULL, bRgbByteOrder, 0, pIccTransform)) { - return FALSE; - } - int dest_Bpp = m_bpp / 8; - int src_Bpp = pSrcBitmap->GetBPP() / 8; - FX_BOOL bRgb = src_Bpp > 1 && !pSrcBitmap->IsCmykImage(); - CFX_DIBitmap* pSrcAlphaMask = pSrcBitmap->m_pAlphaMask; - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = m_pBuffer + (dest_top + row) * m_Pitch + dest_left * dest_Bpp; - const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * src_Bpp; - const uint8_t* src_scan_extra_alpha = pSrcAlphaMask ? pSrcAlphaMask->GetScanline(src_top + row) + src_left : NULL; - uint8_t* dst_scan_extra_alpha = m_pAlphaMask ? (uint8_t*)m_pAlphaMask->GetScanline(dest_top + row) + dest_left : NULL; - const uint8_t* clip_scan = NULL; - if (pClipMask) { - clip_scan = pClipMask->m_pBuffer + (dest_top + row - clip_box.top) * pClipMask->m_Pitch + (dest_left - clip_box.left); - } - if (bRgb) { - compositor.CompositeRgbBitmapLine(dest_scan, src_scan, width, clip_scan, src_scan_extra_alpha, dst_scan_extra_alpha); - } else { - compositor.CompositePalBitmapLine(dest_scan, src_scan, src_left, width, clip_scan, src_scan_extra_alpha, dst_scan_extra_alpha); - } +inline void _CompositeRow_1bppRgb2Rgb_NoBlend_RgbByteOrder( + uint8_t* dest_scan, + const uint8_t* src_scan, + int src_left, + FX_ARGB* pPalette, + int pixel_count, + int DestBpp, + const uint8_t* clip_scan) { + int reset_r, reset_g, reset_b; + int set_r, set_g, set_b; + if (pPalette) { + reset_r = FXARGB_R(pPalette[0]); + reset_g = FXARGB_G(pPalette[0]); + reset_b = FXARGB_B(pPalette[0]); + set_r = FXARGB_R(pPalette[1]); + set_g = FXARGB_G(pPalette[1]); + set_b = FXARGB_B(pPalette[1]); + } else { + reset_r = reset_g = reset_b = 0; + set_r = set_g = set_b = 255; + } + for (int col = 0; col < pixel_count; col++) { + int src_r, src_g, src_b; + if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) { + src_r = set_r; + src_g = set_g; + src_b = set_b; + } else { + src_r = reset_r; + src_g = reset_g; + src_b = reset_b; + } + if (clip_scan && clip_scan[col] < 255) { + dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, clip_scan[col]); + dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, clip_scan[col]); + dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, clip_scan[col]); + } else { + dest_scan[2] = src_b; + dest_scan[1] = src_g; + dest_scan[0] = src_r; } - return TRUE; + dest_scan += DestBpp; + } } -FX_BOOL CFX_DIBitmap::CompositeMask(int dest_left, int dest_top, int width, int height, - const CFX_DIBSource* pMask, FX_DWORD color, int src_left, int src_top, - int blend_type, const CFX_ClipRgn* pClipRgn, FX_BOOL bRgbByteOrder, int alpha_flag, void* pIccTransform) -{ - if (m_pBuffer == NULL) { - return FALSE; - } - ASSERT(pMask->IsAlphaMask()); - ASSERT(m_bpp >= 8); - if (!pMask->IsAlphaMask() || m_bpp < 8) { - return FALSE; - } - GetOverlapRect(dest_left, dest_top, width, height, pMask->GetWidth(), pMask->GetHeight(), src_left, src_top, pClipRgn); - if (width == 0 || height == 0) { - return TRUE; - } - int src_alpha = (uint8_t)(alpha_flag >> 8) ? (alpha_flag & 0xff) : FXARGB_A(color); +inline void _CompositeRow_8bppRgb2Argb_NoBlend_RgbByteOrder( + uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + FX_ARGB* pPalette, + const uint8_t* clip_scan) { + for (int col = 0; col < width; col++) { + int src_r, src_g, src_b; + if (pPalette) { + FX_ARGB argb = pPalette[*src_scan]; + src_r = FXARGB_R(argb); + src_g = FXARGB_G(argb); + src_b = FXARGB_B(argb); + } else { + src_r = src_g = src_b = *src_scan; + } + if (clip_scan == NULL || clip_scan[col] == 255) { + dest_scan[2] = FX_GAMMA(src_b); + dest_scan[1] = FX_GAMMA(src_g); + dest_scan[0] = FX_GAMMA(src_r); + dest_scan[3] = 255; + src_scan++; + dest_scan += 4; + continue; + } + int src_alpha = clip_scan[col]; if (src_alpha == 0) { - return TRUE; - } - const CFX_DIBitmap* pClipMask = NULL; - FX_RECT clip_box; - if (pClipRgn && pClipRgn->GetType() != CFX_ClipRgn::RectI) { - ASSERT(pClipRgn->GetType() == CFX_ClipRgn::MaskF); - pClipMask = pClipRgn->GetMask(); - clip_box = pClipRgn->GetBox(); - } - int src_bpp = pMask->GetBPP(); - int Bpp = GetBPP() / 8; - CFX_ScanlineCompositor compositor; - if (!compositor.Init(GetFormat(), pMask->GetFormat(), width, NULL, color, blend_type, pClipMask != NULL, bRgbByteOrder, alpha_flag, pIccTransform)) { - return FALSE; - } - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = m_pBuffer + (dest_top + row) * m_Pitch + dest_left * Bpp; - const uint8_t* src_scan = pMask->GetScanline(src_top + row); - uint8_t* dst_scan_extra_alpha = m_pAlphaMask ? (uint8_t*)m_pAlphaMask->GetScanline(dest_top + row) + dest_left : NULL; - const uint8_t* clip_scan = NULL; - if (pClipMask) { - clip_scan = pClipMask->m_pBuffer + (dest_top + row - clip_box.top) * pClipMask->m_Pitch + (dest_left - clip_box.left); - } - if (src_bpp == 1) { - compositor.CompositeBitMaskLine(dest_scan, src_scan, src_left, width, clip_scan, dst_scan_extra_alpha); - } else { - compositor.CompositeByteMaskLine(dest_scan, src_scan + src_left, width, clip_scan, dst_scan_extra_alpha); - } - } - return TRUE; + dest_scan += 4; + src_scan++; + continue; + } + int back_alpha = dest_scan[3]; + uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; + dest_scan[3] = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + dest_scan[2] = + FXDIB_ALPHA_MERGE(dest_scan[2], FX_GAMMA(src_b), alpha_ratio); + dest_scan[1] = + FXDIB_ALPHA_MERGE(dest_scan[1], FX_GAMMA(src_g), alpha_ratio); + dest_scan[0] = + FXDIB_ALPHA_MERGE(dest_scan[0], FX_GAMMA(src_r), alpha_ratio); + dest_scan += 4; + src_scan++; + } } -FX_BOOL CFX_DIBitmap::CompositeRect(int left, int top, int width, int height, FX_DWORD color, int alpha_flag, void* pIccTransform) -{ - if (m_pBuffer == NULL) { - return FALSE; - } - int src_alpha = (alpha_flag >> 8) ? (alpha_flag & 0xff) : FXARGB_A(color); +inline void _CompositeRow_1bppRgb2Argb_NoBlend_RgbByteOrder( + uint8_t* dest_scan, + const uint8_t* src_scan, + int src_left, + int width, + FX_ARGB* pPalette, + const uint8_t* clip_scan) { + int reset_r, reset_g, reset_b; + int set_r, set_g, set_b; + if (pPalette) { + reset_r = FXARGB_R(pPalette[0]); + reset_g = FXARGB_G(pPalette[0]); + reset_b = FXARGB_B(pPalette[0]); + set_r = FXARGB_R(pPalette[1]); + set_g = FXARGB_G(pPalette[1]); + set_b = FXARGB_B(pPalette[1]); + } else { + reset_r = reset_g = reset_b = 0; + set_r = set_g = set_b = 255; + } + for (int col = 0; col < width; col++) { + int src_r, src_g, src_b; + if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) { + src_r = set_r; + src_g = set_g; + src_b = set_b; + } else { + src_r = reset_r; + src_g = reset_g; + src_b = reset_b; + } + if (clip_scan == NULL || clip_scan[col] == 255) { + dest_scan[2] = FX_GAMMA(src_b); + dest_scan[1] = FX_GAMMA(src_g); + dest_scan[0] = FX_GAMMA(src_r); + dest_scan[3] = 255; + dest_scan += 4; + continue; + } + int src_alpha = clip_scan[col]; if (src_alpha == 0) { - return TRUE; + dest_scan += 4; + continue; + } + int back_alpha = dest_scan[3]; + uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; + dest_scan[3] = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + dest_scan[2] = + FXDIB_ALPHA_MERGE(dest_scan[2], FX_GAMMA(src_b), alpha_ratio); + dest_scan[1] = + FXDIB_ALPHA_MERGE(dest_scan[1], FX_GAMMA(src_g), alpha_ratio); + dest_scan[0] = + FXDIB_ALPHA_MERGE(dest_scan[0], FX_GAMMA(src_r), alpha_ratio); + dest_scan += 4; + } +} +void _CompositeRow_ByteMask2Argb_RgbByteOrder(uint8_t* dest_scan, + const uint8_t* src_scan, + int mask_alpha, + int src_r, + int src_g, + int src_b, + int pixel_count, + int blend_type, + const uint8_t* clip_scan) { + for (int col = 0; col < pixel_count; col++) { + int src_alpha; + if (clip_scan) { + src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255; + } else { + src_alpha = mask_alpha * src_scan[col] / 255; } - FX_RECT rect(left, top, left + width, top + height); - rect.Intersect(0, 0, m_Width, m_Height); - if (rect.IsEmpty()) { - return TRUE; + uint8_t back_alpha = dest_scan[3]; + if (back_alpha == 0) { + FXARGB_SETRGBORDERDIB(dest_scan, + FXARGB_MAKE(src_alpha, src_r, src_g, src_b)); + dest_scan += 4; + continue; } - width = rect.Width(); - FX_DWORD dst_color; - if (alpha_flag >> 8) { - dst_color = FXCMYK_TODIB(color); + if (src_alpha == 0) { + dest_scan += 4; + continue; + } + uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; + dest_scan[3] = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + if (blend_type >= FXDIB_BLEND_NONSEPARABLE) { + int blended_colors[3]; + uint8_t src_scan[3]; + uint8_t dest_scan_o[3]; + src_scan[0] = src_b; + src_scan[1] = src_g; + src_scan[2] = src_r; + dest_scan_o[0] = dest_scan[2]; + dest_scan_o[1] = dest_scan[1]; + dest_scan_o[2] = dest_scan[0]; + _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors); + dest_scan[2] = + FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], alpha_ratio); + dest_scan[1] = + FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], alpha_ratio); + dest_scan[0] = + FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], alpha_ratio); + } else if (blend_type) { + int blended = _BLEND(blend_type, dest_scan[2], src_b); + blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha); + dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended, alpha_ratio); + blended = _BLEND(blend_type, dest_scan[1], src_g); + blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha); + dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended, alpha_ratio); + blended = _BLEND(blend_type, dest_scan[0], src_r); + blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha); + dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended, alpha_ratio); } else { - dst_color = FXARGB_TODIB(color); - } - uint8_t* color_p = (uint8_t*)&dst_color; - if (m_bpp == 8) { - uint8_t gray = 255; - if (!IsAlphaMask()) { - if (pIccTransform && CFX_GEModule::Get()->GetCodecModule() && CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) { - ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - pIccModule->TranslateScanline(pIccTransform, &gray, color_p, 1); - } else { - if (alpha_flag >> 8) { - uint8_t r, g, b; - AdobeCMYK_to_sRGB1(color_p[0], color_p[1], color_p[2], color_p[3], - r, g, b); - gray = FXRGB2GRAY(r, g, b); - } else { - gray = (uint8_t)FXRGB2GRAY((int)color_p[2], color_p[1], color_p[0]); - } - } - if (IsCmykImage()) { - gray = ~gray; - } - } - for (int row = rect.top; row < rect.bottom; row ++) { - uint8_t* dest_scan = m_pBuffer + row * m_Pitch + rect.left; - if (src_alpha == 255) { - FXSYS_memset(dest_scan, gray, width); - } else - for (int col = 0; col < width; col ++) { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha); - dest_scan ++; - } - } - return TRUE; - } - if (m_bpp == 1) { - ASSERT(!IsCmykImage() && (uint8_t)(alpha_flag >> 8) == 0); - int left_shift = rect.left % 8; - int right_shift = rect.right % 8; - int width = rect.right / 8 - rect.left / 8; - int index = 0; - if (m_pPalette == NULL) { - index = ((uint8_t)color == 0xff) ? 1 : 0; - } else { - for (int i = 0; i < 2; i ++) - if (m_pPalette[i] == color) { - index = i; - } - } - for (int row = rect.top; row < rect.bottom; row ++) { - uint8_t* dest_scan_top = (uint8_t*)GetScanline(row) + rect.left / 8; - uint8_t* dest_scan_top_r = (uint8_t*)GetScanline(row) + rect.right / 8; - uint8_t left_flag = *dest_scan_top & (255 << (8 - left_shift)); - uint8_t right_flag = *dest_scan_top_r & (255 >> right_shift); - if (width) { - FXSYS_memset(dest_scan_top + 1, index ? 255 : 0, width - 1); - if (!index) { - *dest_scan_top &= left_flag; - *dest_scan_top_r &= right_flag; - } else { - *dest_scan_top |= ~left_flag; - *dest_scan_top_r |= ~right_flag; - } - } else { - if (!index) { - *dest_scan_top &= left_flag | right_flag; - } else { - *dest_scan_top |= ~(left_flag | right_flag); - } - } - } - return TRUE; + dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, alpha_ratio); + dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, alpha_ratio); + dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, alpha_ratio); } - ASSERT(m_bpp >= 24); - if (m_bpp < 24) { - return FALSE; + dest_scan += 4; + } +} +void _CompositeRow_ByteMask2Rgb_RgbByteOrder(uint8_t* dest_scan, + const uint8_t* src_scan, + int mask_alpha, + int src_r, + int src_g, + int src_b, + int pixel_count, + int blend_type, + int Bpp, + const uint8_t* clip_scan) { + for (int col = 0; col < pixel_count; col++) { + int src_alpha; + if (clip_scan) { + src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255; + } else { + src_alpha = mask_alpha * src_scan[col] / 255; } - if (pIccTransform && CFX_GEModule::Get()->GetCodecModule()) { - ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - pIccModule->TranslateScanline(pIccTransform, color_p, color_p, 1); + if (src_alpha == 0) { + dest_scan += Bpp; + continue; + } + if (blend_type >= FXDIB_BLEND_NONSEPARABLE) { + int blended_colors[3]; + uint8_t src_scan[3]; + uint8_t dest_scan_o[3]; + src_scan[0] = src_b; + src_scan[1] = src_g; + src_scan[2] = src_r; + dest_scan_o[0] = dest_scan[2]; + dest_scan_o[1] = dest_scan[1]; + dest_scan_o[2] = dest_scan[0]; + _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors); + dest_scan[2] = + FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], src_alpha); + dest_scan[1] = + FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], src_alpha); + dest_scan[0] = + FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], src_alpha); + } else if (blend_type) { + int blended = _BLEND(blend_type, dest_scan[2], src_b); + dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended, src_alpha); + blended = _BLEND(blend_type, dest_scan[1], src_g); + dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended, src_alpha); + blended = _BLEND(blend_type, dest_scan[0], src_r); + dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended, src_alpha); } else { - if (alpha_flag >> 8 && !IsCmykImage()) - AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), FXSYS_GetYValue(color), FXSYS_GetKValue(color), - color_p[2], color_p[1], color_p[0]); - else if (!(alpha_flag >> 8) && IsCmykImage()) { - return FALSE; - } + dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, src_alpha); + dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, src_alpha); + dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, src_alpha); } - if(!IsCmykImage()) { - color_p[3] = (uint8_t)src_alpha; + dest_scan += Bpp; + } +} +void _CompositeRow_BitMask2Argb_RgbByteOrder(uint8_t* dest_scan, + const uint8_t* src_scan, + int mask_alpha, + int src_r, + int src_g, + int src_b, + int src_left, + int pixel_count, + int blend_type, + const uint8_t* clip_scan) { + if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && + mask_alpha == 255) { + FX_ARGB argb = FXARGB_MAKE(0xff, src_r, src_g, src_b); + for (int col = 0; col < pixel_count; col++) { + if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) { + FXARGB_SETRGBORDERDIB(dest_scan, argb); + } + dest_scan += 4; + } + return; + } + for (int col = 0; col < pixel_count; col++) { + if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) { + dest_scan += 4; + continue; + } + int src_alpha; + if (clip_scan) { + src_alpha = mask_alpha * clip_scan[col] / 255; + } else { + src_alpha = mask_alpha; + } + uint8_t back_alpha = dest_scan[3]; + if (back_alpha == 0) { + FXARGB_SETRGBORDERDIB(dest_scan, + FXARGB_MAKE(src_alpha, src_r, src_g, src_b)); + dest_scan += 4; + continue; + } + uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; + dest_scan[3] = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + if (blend_type >= FXDIB_BLEND_NONSEPARABLE) { + int blended_colors[3]; + uint8_t src_scan[3]; + uint8_t dest_scan_o[3]; + src_scan[0] = src_b; + src_scan[1] = src_g; + src_scan[2] = src_r; + dest_scan_o[0] = dest_scan[2]; + dest_scan_o[1] = dest_scan[1]; + dest_scan_o[2] = dest_scan[0]; + _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors); + dest_scan[2] = + FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], alpha_ratio); + dest_scan[1] = + FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], alpha_ratio); + dest_scan[0] = + FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], alpha_ratio); + } else if (blend_type) { + int blended = _BLEND(blend_type, dest_scan[2], src_b); + blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha); + dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended, alpha_ratio); + blended = _BLEND(blend_type, dest_scan[1], src_g); + blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha); + dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended, alpha_ratio); + blended = _BLEND(blend_type, dest_scan[0], src_r); + blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha); + dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended, alpha_ratio); + } else { + dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, alpha_ratio); + dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, alpha_ratio); + dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, alpha_ratio); } - int Bpp = m_bpp / 8; - FX_BOOL bAlpha = HasAlpha(); - FX_BOOL bArgb = GetFormat() == FXDIB_Argb ? TRUE : FALSE; - if (src_alpha == 255) { - for (int row = rect.top; row < rect.bottom; row ++) { - uint8_t* dest_scan = m_pBuffer + row * m_Pitch + rect.left * Bpp; - uint8_t* dest_scan_alpha = m_pAlphaMask ? (uint8_t*)m_pAlphaMask->GetScanline(row) + rect.left : NULL; - if (dest_scan_alpha) { - FXSYS_memset(dest_scan_alpha, 0xff, width); - } - if (Bpp == 4) { - FX_DWORD* scan = (FX_DWORD*)dest_scan; - for (int col = 0; col < width; col ++) { - *scan ++ = dst_color; - } - } else { - for (int col = 0; col < width; col ++) { - *dest_scan ++ = color_p[0]; - *dest_scan ++ = color_p[1]; - *dest_scan ++ = color_p[2]; - } - } - } - return TRUE; - } - for (int row = rect.top; row < rect.bottom; row ++) { - uint8_t* dest_scan = m_pBuffer + row * m_Pitch + rect.left * Bpp; - if (bAlpha) { - if (bArgb) { - for (int col = 0; col < width; col ++) { - uint8_t back_alpha = dest_scan[3]; - if (back_alpha == 0) { - FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, color_p[2], color_p[1], color_p[0])); - dest_scan += 4; - continue; - } - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - int alpha_ratio = src_alpha * 255 / dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[0], alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[1], alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[2], alpha_ratio); - dest_scan ++; - *dest_scan++ = dest_alpha; - } - } else { - uint8_t* dest_scan_alpha = (uint8_t*)m_pAlphaMask->GetScanline(row) + rect.left; - for (int col = 0; col < width; col ++) { - uint8_t back_alpha = *dest_scan_alpha; - if (back_alpha == 0) { - *dest_scan_alpha++ = src_alpha; - FXSYS_memcpy(dest_scan, color_p, Bpp); - dest_scan += Bpp; - continue; - } - uint8_t dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255; - *dest_scan_alpha ++ = dest_alpha; - int alpha_ratio = src_alpha * 255 / dest_alpha; - for(int comps = 0; comps < Bpp; comps ++) { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[comps], alpha_ratio); - dest_scan ++; - } - } - } - } else { - for (int col = 0; col < width; col ++) { - for(int comps = 0; comps < Bpp; comps ++) { - if (comps == 3) { - *dest_scan ++ = 255; - continue; - } - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[comps], src_alpha); - dest_scan ++; - } - } - } + dest_scan += 4; + } +} +void _CompositeRow_BitMask2Rgb_RgbByteOrder(uint8_t* dest_scan, + const uint8_t* src_scan, + int mask_alpha, + int src_r, + int src_g, + int src_b, + int src_left, + int pixel_count, + int blend_type, + int Bpp, + const uint8_t* clip_scan) { + if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && + mask_alpha == 255) { + for (int col = 0; col < pixel_count; col++) { + if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) { + dest_scan[2] = src_b; + dest_scan[1] = src_g; + dest_scan[0] = src_r; + } + dest_scan += Bpp; + } + return; + } + for (int col = 0; col < pixel_count; col++) { + if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) { + dest_scan += Bpp; + continue; + } + int src_alpha; + if (clip_scan) { + src_alpha = mask_alpha * clip_scan[col] / 255; + } else { + src_alpha = mask_alpha; } + if (src_alpha == 0) { + dest_scan += Bpp; + continue; + } + if (blend_type >= FXDIB_BLEND_NONSEPARABLE) { + int blended_colors[3]; + uint8_t src_scan[3]; + uint8_t dest_scan_o[3]; + src_scan[0] = src_b; + src_scan[1] = src_g; + src_scan[2] = src_r; + dest_scan_o[0] = dest_scan[2]; + dest_scan_o[1] = dest_scan[1]; + dest_scan_o[2] = dest_scan[0]; + _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors); + dest_scan[2] = + FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], src_alpha); + dest_scan[1] = + FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], src_alpha); + dest_scan[0] = + FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], src_alpha); + } else if (blend_type) { + int back_color = FX_GAMMA(dest_scan[2]); + int blended = _BLEND(blend_type, back_color, src_b); + dest_scan[2] = + FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha)); + back_color = FX_GAMMA(dest_scan[1]); + blended = _BLEND(blend_type, back_color, src_g); + dest_scan[1] = + FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha)); + back_color = FX_GAMMA(dest_scan[0]); + blended = _BLEND(blend_type, back_color, src_r); + dest_scan[0] = + FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha)); + } else { + dest_scan[2] = FX_GAMMA_INVERSE( + FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), src_b, src_alpha)); + dest_scan[1] = FX_GAMMA_INVERSE( + FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), src_g, src_alpha)); + dest_scan[0] = FX_GAMMA_INVERSE( + FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), src_r, src_alpha)); + } + dest_scan += Bpp; + } +} +inline FX_BOOL _ScanlineCompositor_InitSourceMask(FXDIB_Format dest_format, + int alpha_flag, + FX_DWORD mask_color, + int& mask_alpha, + int& mask_red, + int& mask_green, + int& mask_blue, + int& mask_black, + void* icc_module, + void* pIccTransform) { + ICodec_IccModule* pIccModule = (ICodec_IccModule*)icc_module; + if (alpha_flag >> 8) { + mask_alpha = alpha_flag & 0xff; + mask_red = FXSYS_GetCValue(mask_color); + mask_green = FXSYS_GetMValue(mask_color); + mask_blue = FXSYS_GetYValue(mask_color); + mask_black = FXSYS_GetKValue(mask_color); + } else { + mask_alpha = FXARGB_A(mask_color); + mask_red = FXARGB_R(mask_color); + mask_green = FXARGB_G(mask_color); + mask_blue = FXARGB_B(mask_color); + } + if (dest_format == FXDIB_8bppMask) { return TRUE; + } + if ((dest_format & 0xff) == 8) { + if (pIccTransform) { + mask_color = (alpha_flag >> 8) ? FXCMYK_TODIB(mask_color) + : FXARGB_TODIB(mask_color); + uint8_t* gray_p = (uint8_t*)&mask_color; + pIccModule->TranslateScanline(pIccTransform, gray_p, gray_p, 1); + mask_red = dest_format & 0x0400 ? FX_CCOLOR(gray_p[0]) : gray_p[0]; + } else { + if (alpha_flag >> 8) { + uint8_t r, g, b; + AdobeCMYK_to_sRGB1(mask_red, mask_green, mask_blue, mask_black, r, g, + b); + mask_red = FXRGB2GRAY(r, g, b); + } else { + mask_red = FXRGB2GRAY(mask_red, mask_green, mask_blue); + } + if (dest_format & 0x0400) { + mask_red = FX_CCOLOR(mask_red); + } + } + } else { + uint8_t* mask_color_p = (uint8_t*)&mask_color; + mask_color = + (alpha_flag >> 8) ? FXCMYK_TODIB(mask_color) : FXARGB_TODIB(mask_color); + if (pIccTransform) { + pIccModule->TranslateScanline(pIccTransform, mask_color_p, mask_color_p, + 1); + mask_red = mask_color_p[2]; + mask_green = mask_color_p[1]; + mask_blue = mask_color_p[0]; + } else if (alpha_flag >> 8) { + AdobeCMYK_to_sRGB1(mask_color_p[0], mask_color_p[1], mask_color_p[2], + mask_color_p[3], mask_color_p[2], mask_color_p[1], + mask_color_p[0]); + mask_red = mask_color_p[2]; + mask_green = mask_color_p[1]; + mask_blue = mask_color_p[0]; + } + } + return TRUE; } -CFX_BitmapComposer::CFX_BitmapComposer() -{ - m_pScanlineV = NULL; - m_pScanlineAlphaV = NULL; - m_pClipScanV = NULL; - m_pAddClipScan = NULL; - m_bRgbByteOrder = FALSE; - m_BlendType = FXDIB_BLEND_NORMAL; +inline void _ScanlineCompositor_InitSourcePalette(FXDIB_Format src_format, + FXDIB_Format dest_format, + FX_DWORD*& pDestPalette, + FX_DWORD* pSrcPalette, + void* icc_module, + void* pIccTransform) { + ICodec_IccModule* pIccModule = (ICodec_IccModule*)icc_module; + FX_BOOL isSrcCmyk = src_format & 0x0400 ? TRUE : FALSE; + FX_BOOL isDstCmyk = dest_format & 0x0400 ? TRUE : FALSE; + pDestPalette = NULL; + if (pIccTransform) { + if (pSrcPalette) { + if ((dest_format & 0xff) == 8) { + int pal_count = 1 << (src_format & 0xff); + uint8_t* gray_pal = FX_Alloc(uint8_t, pal_count); + pDestPalette = (FX_DWORD*)gray_pal; + for (int i = 0; i < pal_count; i++) { + FX_DWORD color = isSrcCmyk ? FXCMYK_TODIB(pSrcPalette[i]) + : FXARGB_TODIB(pSrcPalette[i]); + pIccModule->TranslateScanline(pIccTransform, gray_pal, + (const uint8_t*)&color, 1); + gray_pal++; + } + } else { + int palsize = 1 << (src_format & 0xff); + pDestPalette = FX_Alloc(FX_DWORD, palsize); + for (int i = 0; i < palsize; i++) { + FX_DWORD color = isSrcCmyk ? FXCMYK_TODIB(pSrcPalette[i]) + : FXARGB_TODIB(pSrcPalette[i]); + pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&color, + (const uint8_t*)&color, 1); + pDestPalette[i] = + isDstCmyk ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); + } + } + } else { + int pal_count = 1 << (src_format & 0xff); + uint8_t* gray_pal = FX_Alloc(uint8_t, pal_count); + if (pal_count == 2) { + gray_pal[0] = 0; + gray_pal[1] = 255; + } else { + for (int i = 0; i < pal_count; i++) { + gray_pal[i] = i; + } + } + if ((dest_format & 0xff) == 8) { + pIccModule->TranslateScanline(pIccTransform, gray_pal, gray_pal, + pal_count); + pDestPalette = (FX_DWORD*)gray_pal; + } else { + pDestPalette = FX_Alloc(FX_DWORD, pal_count); + for (int i = 0; i < pal_count; i++) { + pIccModule->TranslateScanline( + pIccTransform, (uint8_t*)&pDestPalette[i], &gray_pal[i], 1); + pDestPalette[i] = isDstCmyk ? FXCMYK_TODIB(pDestPalette[i]) + : FXARGB_TODIB(pDestPalette[i]); + } + FX_Free(gray_pal); + } + } + } else { + if (pSrcPalette) { + if ((dest_format & 0xff) == 8) { + int pal_count = 1 << (src_format & 0xff); + uint8_t* gray_pal = FX_Alloc(uint8_t, pal_count); + pDestPalette = (FX_DWORD*)gray_pal; + if (isSrcCmyk) { + for (int i = 0; i < pal_count; i++) { + FX_CMYK cmyk = pSrcPalette[i]; + uint8_t r, g, b; + AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk), + FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk), r, + g, b); + *gray_pal++ = FXRGB2GRAY(r, g, b); + } + } else + for (int i = 0; i < pal_count; i++) { + FX_ARGB argb = pSrcPalette[i]; + *gray_pal++ = + FXRGB2GRAY(FXARGB_R(argb), FXARGB_G(argb), FXARGB_B(argb)); + } + } else { + int palsize = 1 << (src_format & 0xff); + pDestPalette = FX_Alloc(FX_DWORD, palsize); + if (isDstCmyk == isSrcCmyk) { + FXSYS_memcpy(pDestPalette, pSrcPalette, palsize * sizeof(FX_DWORD)); + } else { + for (int i = 0; i < palsize; i++) { + FX_CMYK cmyk = pSrcPalette[i]; + uint8_t r, g, b; + AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk), + FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk), r, + g, b); + pDestPalette[i] = FXARGB_MAKE(0xff, r, g, b); + } + } + } + } else { + if ((dest_format & 0xff) == 8) { + int pal_count = 1 << (src_format & 0xff); + uint8_t* gray_pal = FX_Alloc(uint8_t, pal_count); + if (pal_count == 2) { + gray_pal[0] = 0; + gray_pal[1] = 255; + } else { + for (int i = 0; i < pal_count; i++) { + gray_pal[i] = i; + } + } + pDestPalette = (FX_DWORD*)gray_pal; + } else { + int palsize = 1 << (src_format & 0xff); + pDestPalette = FX_Alloc(FX_DWORD, palsize); + if (palsize == 2) { + pDestPalette[0] = isSrcCmyk ? 255 : 0xff000000; + pDestPalette[1] = isSrcCmyk ? 0 : 0xffffffff; + } else { + for (int i = 0; i < palsize; i++) { + pDestPalette[i] = isSrcCmyk ? FX_CCOLOR(i) : (i * 0x10101); + } + } + if (isSrcCmyk != isDstCmyk) { + for (int i = 0; i < palsize; i++) { + FX_CMYK cmyk = pDestPalette[i]; + uint8_t r, g, b; + AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk), + FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk), r, + g, b); + pDestPalette[i] = FXARGB_MAKE(0xff, r, g, b); + } + } + } + } + } } -CFX_BitmapComposer::~CFX_BitmapComposer() -{ - if (m_pScanlineV) { - FX_Free(m_pScanlineV); - } - if (m_pScanlineAlphaV) { - FX_Free(m_pScanlineAlphaV); - } - if (m_pClipScanV) { - FX_Free(m_pClipScanV); - } - if (m_pAddClipScan) { - FX_Free(m_pAddClipScan); - } +CFX_ScanlineCompositor::CFX_ScanlineCompositor() { + m_pSrcPalette = NULL; + m_pCacheScanline = NULL; + m_CacheSize = 0; + m_bRgbByteOrder = FALSE; + m_BlendType = FXDIB_BLEND_NORMAL; } -void CFX_BitmapComposer::Compose(CFX_DIBitmap* pDest, const CFX_ClipRgn* pClipRgn, int bitmap_alpha, - FX_DWORD mask_color, FX_RECT& dest_rect, FX_BOOL bVertical, - FX_BOOL bFlipX, FX_BOOL bFlipY, FX_BOOL bRgbByteOrder, - int alpha_flag, void* pIccTransform, int blend_type) -{ - m_pBitmap = pDest; - m_pClipRgn = pClipRgn; - m_DestLeft = dest_rect.left; - m_DestTop = dest_rect.top; - m_DestWidth = dest_rect.Width(); - m_DestHeight = dest_rect.Height(); - m_BitmapAlpha = bitmap_alpha; - m_MaskColor = mask_color; - m_pClipMask = NULL; - if (pClipRgn && pClipRgn->GetType() != CFX_ClipRgn::RectI) { - m_pClipMask = pClipRgn->GetMask(); - } - m_bVertical = bVertical; - m_bFlipX = bFlipX; - m_bFlipY = bFlipY; - m_AlphaFlag = alpha_flag; - m_pIccTransform = pIccTransform; - m_bRgbByteOrder = bRgbByteOrder; - m_BlendType = blend_type; +CFX_ScanlineCompositor::~CFX_ScanlineCompositor() { + if (m_pSrcPalette) { + FX_Free(m_pSrcPalette); + } + if (m_pCacheScanline) { + FX_Free(m_pCacheScanline); + } } -FX_BOOL CFX_BitmapComposer::SetInfo(int width, int height, FXDIB_Format src_format, FX_DWORD* pSrcPalette) -{ - m_SrcFormat = src_format; - if (!m_Compositor.Init(m_pBitmap->GetFormat(), src_format, width, pSrcPalette, m_MaskColor, FXDIB_BLEND_NORMAL, - m_pClipMask != NULL || (m_BitmapAlpha < 255), m_bRgbByteOrder, m_AlphaFlag, m_pIccTransform)) { - return FALSE; - } - if (m_bVertical) { - m_pScanlineV = FX_Alloc(uint8_t, m_pBitmap->GetBPP() / 8 * width + 4); - m_pClipScanV = FX_Alloc(uint8_t, m_pBitmap->GetHeight()); - if (m_pBitmap->m_pAlphaMask) { - m_pScanlineAlphaV = FX_Alloc(uint8_t, width + 4); - } - } - if (m_BitmapAlpha < 255) { - m_pAddClipScan = FX_Alloc(uint8_t, m_bVertical ? m_pBitmap->GetHeight() : m_pBitmap->GetWidth()); - } +FX_BOOL CFX_ScanlineCompositor::Init(FXDIB_Format dest_format, + FXDIB_Format src_format, + int32_t width, + FX_DWORD* pSrcPalette, + FX_DWORD mask_color, + int blend_type, + FX_BOOL bClip, + FX_BOOL bRgbByteOrder, + int alpha_flag, + void* pIccTransform) { + m_SrcFormat = src_format; + m_DestFormat = dest_format; + m_BlendType = blend_type; + m_bRgbByteOrder = bRgbByteOrder; + ICodec_IccModule* pIccModule = NULL; + if (CFX_GEModule::Get()->GetCodecModule()) { + pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + } + if (pIccModule == NULL) { + pIccTransform = NULL; + } + m_pIccTransform = pIccTransform; + if ((dest_format & 0xff) == 1) { + return FALSE; + } + if (m_SrcFormat == FXDIB_1bppMask || m_SrcFormat == FXDIB_8bppMask) { + return _ScanlineCompositor_InitSourceMask( + dest_format, alpha_flag, mask_color, m_MaskAlpha, m_MaskRed, + m_MaskGreen, m_MaskBlue, m_MaskBlack, pIccModule, pIccTransform); + } + if (pIccTransform == NULL && (~src_format & 0x0400) && + (dest_format & 0x0400)) { + return FALSE; + } + if ((m_SrcFormat & 0xff) <= 8) { + if (dest_format == FXDIB_8bppMask) { + return TRUE; + } + _ScanlineCompositor_InitSourcePalette(src_format, dest_format, + m_pSrcPalette, pSrcPalette, + pIccModule, pIccTransform); + m_Transparency = + (dest_format == FXDIB_Argb ? 1 : 0) + (dest_format & 0x0200 ? 2 : 0) + + (dest_format & 0x0400 ? 4 : 0) + ((src_format & 0xff) == 1 ? 8 : 0); return TRUE; + } + m_Transparency = (src_format & 0x0200 ? 0 : 1) + + (dest_format & 0x0200 ? 0 : 2) + + (blend_type == FXDIB_BLEND_NORMAL ? 4 : 0) + + (bClip ? 8 : 0) + (src_format & 0x0400 ? 16 : 0) + + (dest_format & 0x0400 ? 32 : 0) + (pIccTransform ? 64 : 0); + return TRUE; } -void CFX_BitmapComposer::DoCompose(uint8_t* dest_scan, const uint8_t* src_scan, int dest_width, const uint8_t* clip_scan, - const uint8_t* src_extra_alpha, uint8_t* dst_extra_alpha) -{ - if (m_BitmapAlpha < 255) { - if (clip_scan) { - for (int i = 0; i < dest_width; i ++) { - m_pAddClipScan[i] = clip_scan[i] * m_BitmapAlpha / 255; - } - } else { - FXSYS_memset(m_pAddClipScan, m_BitmapAlpha, dest_width); - } - clip_scan = m_pAddClipScan; - } - if (m_SrcFormat == FXDIB_8bppMask) { - m_Compositor.CompositeByteMaskLine(dest_scan, src_scan, dest_width, clip_scan, dst_extra_alpha); - } else if ((m_SrcFormat & 0xff) == 8) { - m_Compositor.CompositePalBitmapLine(dest_scan, src_scan, 0, dest_width, clip_scan, src_extra_alpha, dst_extra_alpha); +void CFX_ScanlineCompositor::CompositeRgbBitmapLine( + uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + const uint8_t* clip_scan, + const uint8_t* src_extra_alpha, + uint8_t* dst_extra_alpha) { + int src_Bpp = (m_SrcFormat & 0xff) >> 3; + int dest_Bpp = (m_DestFormat & 0xff) >> 3; + if (m_bRgbByteOrder) { + switch (m_Transparency) { + case 0: + case 4: + case 8: + case 12: + _CompositeRow_Argb2Argb_RgbByteOrder(dest_scan, src_scan, width, + m_BlendType, clip_scan); + break; + case 1: + _CompositeRow_Rgb2Argb_Blend_NoClip_RgbByteOrder( + dest_scan, src_scan, width, m_BlendType, src_Bpp); + break; + case 2: + case 10: + _CompositeRow_Argb2Rgb_Blend_RgbByteOrder( + dest_scan, src_scan, width, m_BlendType, dest_Bpp, clip_scan); + break; + case 3: + _CompositeRow_Rgb2Rgb_Blend_NoClip_RgbByteOrder( + dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp); + break; + case 5: + _CompositeRow_Rgb2Argb_NoBlend_NoClip_RgbByteOrder(dest_scan, src_scan, + width, src_Bpp); + break; + case 6: + case 14: + _CompositeRow_Argb2Rgb_NoBlend_RgbByteOrder(dest_scan, src_scan, width, + dest_Bpp, clip_scan); + break; + case 7: + _CompositeRow_Rgb2Rgb_NoBlend_NoClip_RgbByteOrder( + dest_scan, src_scan, width, dest_Bpp, src_Bpp); + break; + case 9: + _CompositeRow_Rgb2Argb_Blend_Clip_RgbByteOrder( + dest_scan, src_scan, width, m_BlendType, src_Bpp, clip_scan); + break; + case 11: + _CompositeRow_Rgb2Rgb_Blend_Clip_RgbByteOrder( + dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp, + clip_scan); + break; + case 13: + _CompositeRow_Rgb2Argb_NoBlend_Clip_RgbByteOrder( + dest_scan, src_scan, width, src_Bpp, clip_scan); + break; + case 15: + _CompositeRow_Rgb2Rgb_NoBlend_Clip_RgbByteOrder( + dest_scan, src_scan, width, dest_Bpp, src_Bpp, clip_scan); + break; + } + return; + } + if (m_DestFormat == FXDIB_8bppMask) { + if (m_SrcFormat & 0x0200) { + if (m_SrcFormat == FXDIB_Argb) { + _CompositeRow_Argb2Mask(dest_scan, src_scan, width, clip_scan); + } else { + _CompositeRow_Rgba2Mask(dest_scan, src_extra_alpha, width, clip_scan); + } } else { - m_Compositor.CompositeRgbBitmapLine(dest_scan, src_scan, dest_width, clip_scan, src_extra_alpha, dst_extra_alpha); - } + _CompositeRow_Rgb2Mask(dest_scan, src_scan, width, clip_scan); + } + } else if ((m_DestFormat & 0xff) == 8) { + if (m_DestFormat & 0x0400) { + for (int i = 0; i < width; i++) { + *dest_scan = ~*dest_scan; + dest_scan++; + } + } + if (m_SrcFormat & 0x0200) { + if (m_DestFormat & 0x0200) { + _CompositeRow_Argb2Graya(dest_scan, src_scan, width, m_BlendType, + clip_scan, src_extra_alpha, dst_extra_alpha, + m_pIccTransform); + } else { + _CompositeRow_Argb2Gray(dest_scan, src_scan, width, m_BlendType, + clip_scan, src_extra_alpha, m_pIccTransform); + } + } else { + if (m_DestFormat & 0x0200) { + _CompositeRow_Rgb2Graya(dest_scan, src_scan, src_Bpp, width, + m_BlendType, clip_scan, dst_extra_alpha, + m_pIccTransform); + } else { + _CompositeRow_Rgb2Gray(dest_scan, src_scan, src_Bpp, width, m_BlendType, + clip_scan, m_pIccTransform); + } + } + if (m_DestFormat & 0x0400) { + for (int i = 0; i < width; i++) { + *dest_scan = ~*dest_scan; + dest_scan++; + } + } + } else { + int dest_Size = width * dest_Bpp + 4; + if (dest_Size > m_CacheSize) { + m_pCacheScanline = FX_Realloc(uint8_t, m_pCacheScanline, dest_Size); + if (!m_pCacheScanline) { + return; + } + m_CacheSize = dest_Size; + } + switch (m_Transparency) { + case 0: + case 4: + case 8: + case 4 + 8: { + _CompositeRow_Argb2Argb(dest_scan, src_scan, width, m_BlendType, + clip_scan, dst_extra_alpha, src_extra_alpha); + } break; + case 64: + case 4 + 64: + case 8 + 64: + case 4 + 8 + 64: { + _CompositeRow_Argb2Argb_Transform( + dest_scan, src_scan, width, m_BlendType, clip_scan, dst_extra_alpha, + src_extra_alpha, m_pCacheScanline, m_pIccTransform); + } break; + case 1: + _CompositeRow_Rgb2Argb_Blend_NoClip( + dest_scan, src_scan, width, m_BlendType, src_Bpp, dst_extra_alpha); + break; + case 1 + 64: + _CompositeRow_Rgb2Argb_Blend_NoClip_Transform( + dest_scan, src_scan, width, m_BlendType, src_Bpp, dst_extra_alpha, + m_pCacheScanline, m_pIccTransform); + break; + case 1 + 8: + _CompositeRow_Rgb2Argb_Blend_Clip(dest_scan, src_scan, width, + m_BlendType, src_Bpp, clip_scan, + dst_extra_alpha); + break; + case 1 + 8 + 64: + _CompositeRow_Rgb2Argb_Blend_Clip_Transform( + dest_scan, src_scan, width, m_BlendType, src_Bpp, clip_scan, + dst_extra_alpha, m_pCacheScanline, m_pIccTransform); + break; + case 1 + 4: + _CompositeRow_Rgb2Argb_NoBlend_NoClip(dest_scan, src_scan, width, + src_Bpp, dst_extra_alpha); + break; + case 1 + 4 + 64: + _CompositeRow_Rgb2Argb_NoBlend_NoClip_Transform( + dest_scan, src_scan, width, src_Bpp, dst_extra_alpha, + m_pCacheScanline, m_pIccTransform); + break; + case 1 + 4 + 8: + _CompositeRow_Rgb2Argb_NoBlend_Clip(dest_scan, src_scan, width, src_Bpp, + clip_scan, dst_extra_alpha); + break; + case 1 + 4 + 8 + 64: + _CompositeRow_Rgb2Argb_NoBlend_Clip_Transform( + dest_scan, src_scan, width, src_Bpp, clip_scan, dst_extra_alpha, + m_pCacheScanline, m_pIccTransform); + break; + case 2: + case 2 + 8: + _CompositeRow_Argb2Rgb_Blend(dest_scan, src_scan, width, m_BlendType, + dest_Bpp, clip_scan, src_extra_alpha); + break; + case 2 + 64: + case 2 + 8 + 64: + _CompositeRow_Argb2Rgb_Blend_Transform( + dest_scan, src_scan, width, m_BlendType, dest_Bpp, clip_scan, + src_extra_alpha, m_pCacheScanline, m_pIccTransform); + break; + case 2 + 4: + case 2 + 4 + 8: + _CompositeRow_Argb2Rgb_NoBlend(dest_scan, src_scan, width, dest_Bpp, + clip_scan, src_extra_alpha); + break; + case 2 + 4 + 64: + case 2 + 4 + 8 + 64: + _CompositeRow_Argb2Rgb_NoBlend_Transform( + dest_scan, src_scan, width, dest_Bpp, clip_scan, src_extra_alpha, + m_pCacheScanline, m_pIccTransform); + break; + case 1 + 2: + _CompositeRow_Rgb2Rgb_Blend_NoClip(dest_scan, src_scan, width, + m_BlendType, dest_Bpp, src_Bpp); + break; + case 1 + 2 + 64: + _CompositeRow_Rgb2Rgb_Blend_NoClip_Transform( + dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp, + m_pCacheScanline, m_pIccTransform); + break; + case 1 + 2 + 8: + _CompositeRow_Rgb2Rgb_Blend_Clip(dest_scan, src_scan, width, + m_BlendType, dest_Bpp, src_Bpp, + clip_scan); + break; + case 1 + 2 + 8 + 64: + _CompositeRow_Rgb2Rgb_Blend_Clip_Transform( + dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp, + clip_scan, m_pCacheScanline, m_pIccTransform); + break; + case 1 + 2 + 4: + _CompositeRow_Rgb2Rgb_NoBlend_NoClip(dest_scan, src_scan, width, + dest_Bpp, src_Bpp); + break; + case 1 + 2 + 4 + 64: + _CompositeRow_Rgb2Rgb_NoBlend_NoClip_Transform( + dest_scan, src_scan, width, dest_Bpp, src_Bpp, m_pCacheScanline, + m_pIccTransform); + break; + case 1 + 2 + 4 + 8: + _CompositeRow_Rgb2Rgb_NoBlend_Clip(dest_scan, src_scan, width, dest_Bpp, + src_Bpp, clip_scan); + break; + case 1 + 2 + 4 + 8 + 64: + _CompositeRow_Rgb2Rgb_NoBlend_Clip_Transform( + dest_scan, src_scan, width, dest_Bpp, src_Bpp, clip_scan, + m_pCacheScanline, m_pIccTransform); + break; + } + } } -void CFX_BitmapComposer::ComposeScanline(int line, const uint8_t* scanline, const uint8_t* scan_extra_alpha) -{ - if (m_bVertical) { - ComposeScanlineV(line, scanline, scan_extra_alpha); +void CFX_ScanlineCompositor::CompositePalBitmapLine( + uint8_t* dest_scan, + const uint8_t* src_scan, + int src_left, + int width, + const uint8_t* clip_scan, + const uint8_t* src_extra_alpha, + uint8_t* dst_extra_alpha) { + if (m_bRgbByteOrder) { + if (m_SrcFormat == FXDIB_1bppRgb) { + if (m_DestFormat == FXDIB_8bppRgb) { return; - } + } + if (m_DestFormat == FXDIB_Argb) { + _CompositeRow_1bppRgb2Argb_NoBlend_RgbByteOrder( + dest_scan, src_scan, src_left, width, m_pSrcPalette, clip_scan); + } else { + _CompositeRow_1bppRgb2Rgb_NoBlend_RgbByteOrder( + dest_scan, src_scan, src_left, m_pSrcPalette, width, + (m_DestFormat & 0xff) >> 3, clip_scan); + } + } else { + if (m_DestFormat == FXDIB_8bppRgb) { + return; + } + if (m_DestFormat == FXDIB_Argb) { + _CompositeRow_8bppRgb2Argb_NoBlend_RgbByteOrder( + dest_scan, src_scan, width, m_pSrcPalette, clip_scan); + } else { + _CompositeRow_8bppRgb2Rgb_NoBlend_RgbByteOrder( + dest_scan, src_scan, m_pSrcPalette, width, + (m_DestFormat & 0xff) >> 3, clip_scan); + } + } + return; + } + if (m_DestFormat == FXDIB_8bppMask) { + _CompositeRow_Rgb2Mask(dest_scan, src_scan, width, clip_scan); + return; + } + if ((m_DestFormat & 0xff) == 8) { + if (m_Transparency & 8) { + if (m_DestFormat & 0x0200) { + _CompositeRow_1bppPal2Graya(dest_scan, src_scan, src_left, + (const uint8_t*)m_pSrcPalette, width, + m_BlendType, clip_scan, dst_extra_alpha); + } else { + _CompositeRow_1bppPal2Gray(dest_scan, src_scan, src_left, + (const uint8_t*)m_pSrcPalette, width, + m_BlendType, clip_scan); + } + } else { + if (m_DestFormat & 0x0200) + _CompositeRow_8bppPal2Graya( + dest_scan, src_scan, (const uint8_t*)m_pSrcPalette, width, + m_BlendType, clip_scan, dst_extra_alpha, src_extra_alpha); + else + _CompositeRow_8bppPal2Gray(dest_scan, src_scan, + (const uint8_t*)m_pSrcPalette, width, + m_BlendType, clip_scan, src_extra_alpha); + } + } else { + switch (m_Transparency) { + case 1 + 2: + _CompositeRow_8bppRgb2Argb_NoBlend(dest_scan, src_scan, width, + m_pSrcPalette, clip_scan, + src_extra_alpha); + break; + case 1 + 2 + 8: + _CompositeRow_1bppRgb2Argb_NoBlend(dest_scan, src_scan, src_left, width, + m_pSrcPalette, clip_scan); + break; + case 0: + _CompositeRow_8bppRgb2Rgb_NoBlend(dest_scan, src_scan, m_pSrcPalette, + width, (m_DestFormat & 0xff) >> 3, + clip_scan, src_extra_alpha); + break; + case 0 + 8: + _CompositeRow_1bppRgb2Rgb_NoBlend( + dest_scan, src_scan, src_left, m_pSrcPalette, width, + (m_DestFormat & 0xff) >> 3, clip_scan); + break; + case 0 + 2: + _CompositeRow_8bppRgb2Rgb_NoBlend(dest_scan, src_scan, m_pSrcPalette, + width, (m_DestFormat & 0xff) >> 3, + clip_scan, src_extra_alpha); + break; + case 0 + 2 + 8: + _CompositeRow_1bppRgb2Rgba_NoBlend(dest_scan, src_scan, src_left, width, + m_pSrcPalette, clip_scan, + dst_extra_alpha); + break; + break; + } + } +} +void CFX_ScanlineCompositor::CompositeByteMaskLine(uint8_t* dest_scan, + const uint8_t* src_scan, + int width, + const uint8_t* clip_scan, + uint8_t* dst_extra_alpha) { + if (m_DestFormat == FXDIB_8bppMask) { + _CompositeRow_ByteMask2Mask(dest_scan, src_scan, m_MaskAlpha, width, + clip_scan); + } else if ((m_DestFormat & 0xff) == 8) { + if (m_DestFormat & 0x0200) { + _CompositeRow_ByteMask2Graya(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, + width, clip_scan, dst_extra_alpha); + } else { + _CompositeRow_ByteMask2Gray(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, + width, clip_scan); + } + } else if (m_bRgbByteOrder) { + if (m_DestFormat == FXDIB_Argb) + _CompositeRow_ByteMask2Argb_RgbByteOrder( + dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue, + width, m_BlendType, clip_scan); + else + _CompositeRow_ByteMask2Rgb_RgbByteOrder( + dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue, + width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan); + return; + } else if (m_DestFormat == FXDIB_Argb) + _CompositeRow_ByteMask2Argb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, + m_MaskGreen, m_MaskBlue, width, m_BlendType, + clip_scan); + else if (m_DestFormat == FXDIB_Rgb || m_DestFormat == FXDIB_Rgb32) + _CompositeRow_ByteMask2Rgb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, + m_MaskGreen, m_MaskBlue, width, m_BlendType, + (m_DestFormat & 0xff) >> 3, clip_scan); + else if (m_DestFormat == FXDIB_Rgba) + _CompositeRow_ByteMask2Rgba(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, + m_MaskGreen, m_MaskBlue, width, m_BlendType, + clip_scan, dst_extra_alpha); +} +void CFX_ScanlineCompositor::CompositeBitMaskLine(uint8_t* dest_scan, + const uint8_t* src_scan, + int src_left, + int width, + const uint8_t* clip_scan, + uint8_t* dst_extra_alpha) { + if (m_DestFormat == FXDIB_8bppMask) { + _CompositeRow_BitMask2Mask(dest_scan, src_scan, m_MaskAlpha, src_left, + width, clip_scan); + } else if ((m_DestFormat & 0xff) == 8) { + if (m_DestFormat & 0x0200) + _CompositeRow_BitMask2Graya(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, + src_left, width, clip_scan, dst_extra_alpha); + else { + _CompositeRow_BitMask2Gray(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, + src_left, width, clip_scan); + } + } else if (m_bRgbByteOrder) { + if (m_DestFormat == FXDIB_Argb) + _CompositeRow_BitMask2Argb_RgbByteOrder( + dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue, + src_left, width, m_BlendType, clip_scan); + else + _CompositeRow_BitMask2Rgb_RgbByteOrder( + dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue, + src_left, width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan); + return; + } else if (m_DestFormat == FXDIB_Argb) + _CompositeRow_BitMask2Argb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, + m_MaskGreen, m_MaskBlue, src_left, width, + m_BlendType, clip_scan); + else if (m_DestFormat == FXDIB_Rgb || m_DestFormat == FXDIB_Rgb32) + _CompositeRow_BitMask2Rgb( + dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue, + src_left, width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan); +} +FX_BOOL CFX_DIBitmap::CompositeBitmap(int dest_left, + int dest_top, + int width, + int height, + const CFX_DIBSource* pSrcBitmap, + int src_left, + int src_top, + int blend_type, + const CFX_ClipRgn* pClipRgn, + FX_BOOL bRgbByteOrder, + void* pIccTransform) { + if (m_pBuffer == NULL) { + return FALSE; + } + ASSERT(!pSrcBitmap->IsAlphaMask()); + ASSERT(m_bpp >= 8); + if (pSrcBitmap->IsAlphaMask() || m_bpp < 8) { + return FALSE; + } + GetOverlapRect(dest_left, dest_top, width, height, pSrcBitmap->GetWidth(), + pSrcBitmap->GetHeight(), src_left, src_top, pClipRgn); + if (width == 0 || height == 0) { + return TRUE; + } + const CFX_DIBitmap* pClipMask = NULL; + FX_RECT clip_box; + if (pClipRgn && pClipRgn->GetType() != CFX_ClipRgn::RectI) { + ASSERT(pClipRgn->GetType() == CFX_ClipRgn::MaskF); + pClipMask = pClipRgn->GetMask(); + clip_box = pClipRgn->GetBox(); + } + CFX_ScanlineCompositor compositor; + if (!compositor.Init(GetFormat(), pSrcBitmap->GetFormat(), width, + pSrcBitmap->GetPalette(), 0, blend_type, + pClipMask != NULL, bRgbByteOrder, 0, pIccTransform)) { + return FALSE; + } + int dest_Bpp = m_bpp / 8; + int src_Bpp = pSrcBitmap->GetBPP() / 8; + FX_BOOL bRgb = src_Bpp > 1 && !pSrcBitmap->IsCmykImage(); + CFX_DIBitmap* pSrcAlphaMask = pSrcBitmap->m_pAlphaMask; + for (int row = 0; row < height; row++) { + uint8_t* dest_scan = + m_pBuffer + (dest_top + row) * m_Pitch + dest_left * dest_Bpp; + const uint8_t* src_scan = + pSrcBitmap->GetScanline(src_top + row) + src_left * src_Bpp; + const uint8_t* src_scan_extra_alpha = + pSrcAlphaMask ? pSrcAlphaMask->GetScanline(src_top + row) + src_left + : NULL; + uint8_t* dst_scan_extra_alpha = + m_pAlphaMask + ? (uint8_t*)m_pAlphaMask->GetScanline(dest_top + row) + dest_left + : NULL; const uint8_t* clip_scan = NULL; - if (m_pClipMask) - clip_scan = m_pClipMask->GetBuffer() + (m_DestTop + line - m_pClipRgn->GetBox().top) * - m_pClipMask->GetPitch() + (m_DestLeft - m_pClipRgn->GetBox().left); - uint8_t* dest_scan = (uint8_t*)m_pBitmap->GetScanline(line + m_DestTop) + - m_DestLeft * m_pBitmap->GetBPP() / 8; - uint8_t* dest_alpha_scan = m_pBitmap->m_pAlphaMask ? - (uint8_t*)m_pBitmap->m_pAlphaMask->GetScanline(line + m_DestTop) + m_DestLeft : NULL; - DoCompose(dest_scan, scanline, m_DestWidth, clip_scan, scan_extra_alpha, dest_alpha_scan); + if (pClipMask) { + clip_scan = pClipMask->m_pBuffer + + (dest_top + row - clip_box.top) * pClipMask->m_Pitch + + (dest_left - clip_box.left); + } + if (bRgb) { + compositor.CompositeRgbBitmapLine(dest_scan, src_scan, width, clip_scan, + src_scan_extra_alpha, + dst_scan_extra_alpha); + } else { + compositor.CompositePalBitmapLine(dest_scan, src_scan, src_left, width, + clip_scan, src_scan_extra_alpha, + dst_scan_extra_alpha); + } + } + return TRUE; } -void CFX_BitmapComposer::ComposeScanlineV(int line, const uint8_t* scanline, const uint8_t* scan_extra_alpha) -{ - int i; - int Bpp = m_pBitmap->GetBPP() / 8; - int dest_pitch = m_pBitmap->GetPitch(); - int dest_alpha_pitch = m_pBitmap->m_pAlphaMask ? m_pBitmap->m_pAlphaMask->GetPitch() : 0; - int dest_x = m_DestLeft + (m_bFlipX ? (m_DestWidth - line - 1) : line); - uint8_t* dest_buf = m_pBitmap->GetBuffer() + dest_x * Bpp + m_DestTop * dest_pitch; - uint8_t* dest_alpha_buf = m_pBitmap->m_pAlphaMask ? - m_pBitmap->m_pAlphaMask->GetBuffer() + dest_x + m_DestTop * dest_alpha_pitch : NULL; - if (m_bFlipY) { - dest_buf += dest_pitch * (m_DestHeight - 1); - dest_alpha_buf += dest_alpha_pitch * (m_DestHeight - 1); +FX_BOOL CFX_DIBitmap::CompositeMask(int dest_left, + int dest_top, + int width, + int height, + const CFX_DIBSource* pMask, + FX_DWORD color, + int src_left, + int src_top, + int blend_type, + const CFX_ClipRgn* pClipRgn, + FX_BOOL bRgbByteOrder, + int alpha_flag, + void* pIccTransform) { + if (m_pBuffer == NULL) { + return FALSE; + } + ASSERT(pMask->IsAlphaMask()); + ASSERT(m_bpp >= 8); + if (!pMask->IsAlphaMask() || m_bpp < 8) { + return FALSE; + } + GetOverlapRect(dest_left, dest_top, width, height, pMask->GetWidth(), + pMask->GetHeight(), src_left, src_top, pClipRgn); + if (width == 0 || height == 0) { + return TRUE; + } + int src_alpha = + (uint8_t)(alpha_flag >> 8) ? (alpha_flag & 0xff) : FXARGB_A(color); + if (src_alpha == 0) { + return TRUE; + } + const CFX_DIBitmap* pClipMask = NULL; + FX_RECT clip_box; + if (pClipRgn && pClipRgn->GetType() != CFX_ClipRgn::RectI) { + ASSERT(pClipRgn->GetType() == CFX_ClipRgn::MaskF); + pClipMask = pClipRgn->GetMask(); + clip_box = pClipRgn->GetBox(); + } + int src_bpp = pMask->GetBPP(); + int Bpp = GetBPP() / 8; + CFX_ScanlineCompositor compositor; + if (!compositor.Init(GetFormat(), pMask->GetFormat(), width, NULL, color, + blend_type, pClipMask != NULL, bRgbByteOrder, alpha_flag, + pIccTransform)) { + return FALSE; + } + for (int row = 0; row < height; row++) { + uint8_t* dest_scan = + m_pBuffer + (dest_top + row) * m_Pitch + dest_left * Bpp; + const uint8_t* src_scan = pMask->GetScanline(src_top + row); + uint8_t* dst_scan_extra_alpha = + m_pAlphaMask + ? (uint8_t*)m_pAlphaMask->GetScanline(dest_top + row) + dest_left + : NULL; + const uint8_t* clip_scan = NULL; + if (pClipMask) { + clip_scan = pClipMask->m_pBuffer + + (dest_top + row - clip_box.top) * pClipMask->m_Pitch + + (dest_left - clip_box.left); + } + if (src_bpp == 1) { + compositor.CompositeBitMaskLine(dest_scan, src_scan, src_left, width, + clip_scan, dst_scan_extra_alpha); + } else { + compositor.CompositeByteMaskLine(dest_scan, src_scan + src_left, width, + clip_scan, dst_scan_extra_alpha); } - int y_step = dest_pitch; - int y_alpha_step = dest_alpha_pitch; - if (m_bFlipY) { - y_step = -y_step; - y_alpha_step = -y_alpha_step; - } - uint8_t* src_scan = m_pScanlineV; - uint8_t* dest_scan = dest_buf; - for (i = 0; i < m_DestHeight; i ++) { - for (int j = 0; j < Bpp; j ++) { - *src_scan++ = dest_scan[j]; + } + return TRUE; +} +FX_BOOL CFX_DIBitmap::CompositeRect(int left, + int top, + int width, + int height, + FX_DWORD color, + int alpha_flag, + void* pIccTransform) { + if (m_pBuffer == NULL) { + return FALSE; + } + int src_alpha = (alpha_flag >> 8) ? (alpha_flag & 0xff) : FXARGB_A(color); + if (src_alpha == 0) { + return TRUE; + } + FX_RECT rect(left, top, left + width, top + height); + rect.Intersect(0, 0, m_Width, m_Height); + if (rect.IsEmpty()) { + return TRUE; + } + width = rect.Width(); + FX_DWORD dst_color; + if (alpha_flag >> 8) { + dst_color = FXCMYK_TODIB(color); + } else { + dst_color = FXARGB_TODIB(color); + } + uint8_t* color_p = (uint8_t*)&dst_color; + if (m_bpp == 8) { + uint8_t gray = 255; + if (!IsAlphaMask()) { + if (pIccTransform && CFX_GEModule::Get()->GetCodecModule() && + CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) { + ICodec_IccModule* pIccModule = + CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + pIccModule->TranslateScanline(pIccTransform, &gray, color_p, 1); + } else { + if (alpha_flag >> 8) { + uint8_t r, g, b; + AdobeCMYK_to_sRGB1(color_p[0], color_p[1], color_p[2], color_p[3], r, + g, b); + gray = FXRGB2GRAY(r, g, b); + } else { + gray = (uint8_t)FXRGB2GRAY((int)color_p[2], color_p[1], color_p[0]); } - dest_scan += y_step; - } - uint8_t* src_alpha_scan = m_pScanlineAlphaV; - uint8_t* dest_alpha_scan = dest_alpha_buf; - if (dest_alpha_scan) { - for (i = 0; i < m_DestHeight; i ++) { - *src_alpha_scan++ = *dest_alpha_scan; - dest_alpha_scan += y_alpha_step; + } + if (IsCmykImage()) { + gray = ~gray; + } + } + for (int row = rect.top; row < rect.bottom; row++) { + uint8_t* dest_scan = m_pBuffer + row * m_Pitch + rect.left; + if (src_alpha == 255) { + FXSYS_memset(dest_scan, gray, width); + } else + for (int col = 0; col < width; col++) { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha); + dest_scan++; } } - uint8_t* clip_scan = NULL; - if (m_pClipMask) { - clip_scan = m_pClipScanV; - int clip_pitch = m_pClipMask->GetPitch(); - const uint8_t* src_clip = m_pClipMask->GetBuffer() + (m_DestTop - m_pClipRgn->GetBox().top) * - clip_pitch + (dest_x - m_pClipRgn->GetBox().left); - if (m_bFlipY) { - src_clip += clip_pitch * (m_DestHeight - 1); - clip_pitch = -clip_pitch; + return TRUE; + } + if (m_bpp == 1) { + ASSERT(!IsCmykImage() && (uint8_t)(alpha_flag >> 8) == 0); + int left_shift = rect.left % 8; + int right_shift = rect.right % 8; + int width = rect.right / 8 - rect.left / 8; + int index = 0; + if (m_pPalette == NULL) { + index = ((uint8_t)color == 0xff) ? 1 : 0; + } else { + for (int i = 0; i < 2; i++) + if (m_pPalette[i] == color) { + index = i; + } + } + for (int row = rect.top; row < rect.bottom; row++) { + uint8_t* dest_scan_top = (uint8_t*)GetScanline(row) + rect.left / 8; + uint8_t* dest_scan_top_r = (uint8_t*)GetScanline(row) + rect.right / 8; + uint8_t left_flag = *dest_scan_top & (255 << (8 - left_shift)); + uint8_t right_flag = *dest_scan_top_r & (255 >> right_shift); + if (width) { + FXSYS_memset(dest_scan_top + 1, index ? 255 : 0, width - 1); + if (!index) { + *dest_scan_top &= left_flag; + *dest_scan_top_r &= right_flag; + } else { + *dest_scan_top |= ~left_flag; + *dest_scan_top_r |= ~right_flag; } - for (i = 0; i < m_DestHeight; i ++) { - clip_scan[i] = *src_clip; - src_clip += clip_pitch; + } else { + if (!index) { + *dest_scan_top &= left_flag | right_flag; + } else { + *dest_scan_top |= ~(left_flag | right_flag); } + } + } + return TRUE; + } + ASSERT(m_bpp >= 24); + if (m_bpp < 24) { + return FALSE; + } + if (pIccTransform && CFX_GEModule::Get()->GetCodecModule()) { + ICodec_IccModule* pIccModule = + CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + pIccModule->TranslateScanline(pIccTransform, color_p, color_p, 1); + } else { + if (alpha_flag >> 8 && !IsCmykImage()) + AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), + FXSYS_GetYValue(color), FXSYS_GetKValue(color), + color_p[2], color_p[1], color_p[0]); + else if (!(alpha_flag >> 8) && IsCmykImage()) { + return FALSE; + } + } + if (!IsCmykImage()) { + color_p[3] = (uint8_t)src_alpha; + } + int Bpp = m_bpp / 8; + FX_BOOL bAlpha = HasAlpha(); + FX_BOOL bArgb = GetFormat() == FXDIB_Argb ? TRUE : FALSE; + if (src_alpha == 255) { + for (int row = rect.top; row < rect.bottom; row++) { + uint8_t* dest_scan = m_pBuffer + row * m_Pitch + rect.left * Bpp; + uint8_t* dest_scan_alpha = + m_pAlphaMask ? (uint8_t*)m_pAlphaMask->GetScanline(row) + rect.left + : NULL; + if (dest_scan_alpha) { + FXSYS_memset(dest_scan_alpha, 0xff, width); + } + if (Bpp == 4) { + FX_DWORD* scan = (FX_DWORD*)dest_scan; + for (int col = 0; col < width; col++) { + *scan++ = dst_color; + } + } else { + for (int col = 0; col < width; col++) { + *dest_scan++ = color_p[0]; + *dest_scan++ = color_p[1]; + *dest_scan++ = color_p[2]; + } + } } - DoCompose(m_pScanlineV, scanline, m_DestHeight, clip_scan, scan_extra_alpha, m_pScanlineAlphaV); - src_scan = m_pScanlineV; - dest_scan = dest_buf; - for (i = 0; i < m_DestHeight; i ++) { - for (int j = 0; j < Bpp; j ++) { - dest_scan[j] = *src_scan++; + return TRUE; + } + for (int row = rect.top; row < rect.bottom; row++) { + uint8_t* dest_scan = m_pBuffer + row * m_Pitch + rect.left * Bpp; + if (bAlpha) { + if (bArgb) { + for (int col = 0; col < width; col++) { + uint8_t back_alpha = dest_scan[3]; + if (back_alpha == 0) { + FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, color_p[2], + color_p[1], color_p[0])); + dest_scan += 4; + continue; + } + uint8_t dest_alpha = + back_alpha + src_alpha - back_alpha * src_alpha / 255; + int alpha_ratio = src_alpha * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[0], alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[1], alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[2], alpha_ratio); + dest_scan++; + *dest_scan++ = dest_alpha; + } + } else { + uint8_t* dest_scan_alpha = + (uint8_t*)m_pAlphaMask->GetScanline(row) + rect.left; + for (int col = 0; col < width; col++) { + uint8_t back_alpha = *dest_scan_alpha; + if (back_alpha == 0) { + *dest_scan_alpha++ = src_alpha; + FXSYS_memcpy(dest_scan, color_p, Bpp); + dest_scan += Bpp; + continue; + } + uint8_t dest_alpha = + back_alpha + src_alpha - back_alpha * src_alpha / 255; + *dest_scan_alpha++ = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + for (int comps = 0; comps < Bpp; comps++) { + *dest_scan = + FXDIB_ALPHA_MERGE(*dest_scan, color_p[comps], alpha_ratio); + dest_scan++; + } } - dest_scan += y_step; - } - src_alpha_scan = m_pScanlineAlphaV; - dest_alpha_scan = dest_alpha_buf; - if (dest_alpha_scan) { - for (i = 0; i < m_DestHeight; i ++) { - *dest_alpha_scan = *src_alpha_scan++; - dest_alpha_scan += y_alpha_step; + } + } else { + for (int col = 0; col < width; col++) { + for (int comps = 0; comps < Bpp; comps++) { + if (comps == 3) { + *dest_scan++ = 255; + continue; + } + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[comps], src_alpha); + dest_scan++; } + } } + } + return TRUE; +} +CFX_BitmapComposer::CFX_BitmapComposer() { + m_pScanlineV = NULL; + m_pScanlineAlphaV = NULL; + m_pClipScanV = NULL; + m_pAddClipScan = NULL; + m_bRgbByteOrder = FALSE; + m_BlendType = FXDIB_BLEND_NORMAL; +} +CFX_BitmapComposer::~CFX_BitmapComposer() { + if (m_pScanlineV) { + FX_Free(m_pScanlineV); + } + if (m_pScanlineAlphaV) { + FX_Free(m_pScanlineAlphaV); + } + if (m_pClipScanV) { + FX_Free(m_pClipScanV); + } + if (m_pAddClipScan) { + FX_Free(m_pAddClipScan); + } +} +void CFX_BitmapComposer::Compose(CFX_DIBitmap* pDest, + const CFX_ClipRgn* pClipRgn, + int bitmap_alpha, + FX_DWORD mask_color, + FX_RECT& dest_rect, + FX_BOOL bVertical, + FX_BOOL bFlipX, + FX_BOOL bFlipY, + FX_BOOL bRgbByteOrder, + int alpha_flag, + void* pIccTransform, + int blend_type) { + m_pBitmap = pDest; + m_pClipRgn = pClipRgn; + m_DestLeft = dest_rect.left; + m_DestTop = dest_rect.top; + m_DestWidth = dest_rect.Width(); + m_DestHeight = dest_rect.Height(); + m_BitmapAlpha = bitmap_alpha; + m_MaskColor = mask_color; + m_pClipMask = NULL; + if (pClipRgn && pClipRgn->GetType() != CFX_ClipRgn::RectI) { + m_pClipMask = pClipRgn->GetMask(); + } + m_bVertical = bVertical; + m_bFlipX = bFlipX; + m_bFlipY = bFlipY; + m_AlphaFlag = alpha_flag; + m_pIccTransform = pIccTransform; + m_bRgbByteOrder = bRgbByteOrder; + m_BlendType = blend_type; +} +FX_BOOL CFX_BitmapComposer::SetInfo(int width, + int height, + FXDIB_Format src_format, + FX_DWORD* pSrcPalette) { + m_SrcFormat = src_format; + if (!m_Compositor.Init(m_pBitmap->GetFormat(), src_format, width, pSrcPalette, + m_MaskColor, FXDIB_BLEND_NORMAL, + m_pClipMask != NULL || (m_BitmapAlpha < 255), + m_bRgbByteOrder, m_AlphaFlag, m_pIccTransform)) { + return FALSE; + } + if (m_bVertical) { + m_pScanlineV = FX_Alloc(uint8_t, m_pBitmap->GetBPP() / 8 * width + 4); + m_pClipScanV = FX_Alloc(uint8_t, m_pBitmap->GetHeight()); + if (m_pBitmap->m_pAlphaMask) { + m_pScanlineAlphaV = FX_Alloc(uint8_t, width + 4); + } + } + if (m_BitmapAlpha < 255) { + m_pAddClipScan = FX_Alloc( + uint8_t, m_bVertical ? m_pBitmap->GetHeight() : m_pBitmap->GetWidth()); + } + return TRUE; +} +void CFX_BitmapComposer::DoCompose(uint8_t* dest_scan, + const uint8_t* src_scan, + int dest_width, + const uint8_t* clip_scan, + const uint8_t* src_extra_alpha, + uint8_t* dst_extra_alpha) { + if (m_BitmapAlpha < 255) { + if (clip_scan) { + for (int i = 0; i < dest_width; i++) { + m_pAddClipScan[i] = clip_scan[i] * m_BitmapAlpha / 255; + } + } else { + FXSYS_memset(m_pAddClipScan, m_BitmapAlpha, dest_width); + } + clip_scan = m_pAddClipScan; + } + if (m_SrcFormat == FXDIB_8bppMask) { + m_Compositor.CompositeByteMaskLine(dest_scan, src_scan, dest_width, + clip_scan, dst_extra_alpha); + } else if ((m_SrcFormat & 0xff) == 8) { + m_Compositor.CompositePalBitmapLine(dest_scan, src_scan, 0, dest_width, + clip_scan, src_extra_alpha, + dst_extra_alpha); + } else { + m_Compositor.CompositeRgbBitmapLine(dest_scan, src_scan, dest_width, + clip_scan, src_extra_alpha, + dst_extra_alpha); + } +} +void CFX_BitmapComposer::ComposeScanline(int line, + const uint8_t* scanline, + const uint8_t* scan_extra_alpha) { + if (m_bVertical) { + ComposeScanlineV(line, scanline, scan_extra_alpha); + return; + } + const uint8_t* clip_scan = NULL; + if (m_pClipMask) + clip_scan = m_pClipMask->GetBuffer() + + (m_DestTop + line - m_pClipRgn->GetBox().top) * + m_pClipMask->GetPitch() + + (m_DestLeft - m_pClipRgn->GetBox().left); + uint8_t* dest_scan = (uint8_t*)m_pBitmap->GetScanline(line + m_DestTop) + + m_DestLeft * m_pBitmap->GetBPP() / 8; + uint8_t* dest_alpha_scan = + m_pBitmap->m_pAlphaMask + ? (uint8_t*)m_pBitmap->m_pAlphaMask->GetScanline(line + m_DestTop) + + m_DestLeft + : NULL; + DoCompose(dest_scan, scanline, m_DestWidth, clip_scan, scan_extra_alpha, + dest_alpha_scan); +} +void CFX_BitmapComposer::ComposeScanlineV(int line, + const uint8_t* scanline, + const uint8_t* scan_extra_alpha) { + int i; + int Bpp = m_pBitmap->GetBPP() / 8; + int dest_pitch = m_pBitmap->GetPitch(); + int dest_alpha_pitch = + m_pBitmap->m_pAlphaMask ? m_pBitmap->m_pAlphaMask->GetPitch() : 0; + int dest_x = m_DestLeft + (m_bFlipX ? (m_DestWidth - line - 1) : line); + uint8_t* dest_buf = + m_pBitmap->GetBuffer() + dest_x * Bpp + m_DestTop * dest_pitch; + uint8_t* dest_alpha_buf = m_pBitmap->m_pAlphaMask + ? m_pBitmap->m_pAlphaMask->GetBuffer() + + dest_x + m_DestTop * dest_alpha_pitch + : NULL; + if (m_bFlipY) { + dest_buf += dest_pitch * (m_DestHeight - 1); + dest_alpha_buf += dest_alpha_pitch * (m_DestHeight - 1); + } + int y_step = dest_pitch; + int y_alpha_step = dest_alpha_pitch; + if (m_bFlipY) { + y_step = -y_step; + y_alpha_step = -y_alpha_step; + } + uint8_t* src_scan = m_pScanlineV; + uint8_t* dest_scan = dest_buf; + for (i = 0; i < m_DestHeight; i++) { + for (int j = 0; j < Bpp; j++) { + *src_scan++ = dest_scan[j]; + } + dest_scan += y_step; + } + uint8_t* src_alpha_scan = m_pScanlineAlphaV; + uint8_t* dest_alpha_scan = dest_alpha_buf; + if (dest_alpha_scan) { + for (i = 0; i < m_DestHeight; i++) { + *src_alpha_scan++ = *dest_alpha_scan; + dest_alpha_scan += y_alpha_step; + } + } + uint8_t* clip_scan = NULL; + if (m_pClipMask) { + clip_scan = m_pClipScanV; + int clip_pitch = m_pClipMask->GetPitch(); + const uint8_t* src_clip = + m_pClipMask->GetBuffer() + + (m_DestTop - m_pClipRgn->GetBox().top) * clip_pitch + + (dest_x - m_pClipRgn->GetBox().left); + if (m_bFlipY) { + src_clip += clip_pitch * (m_DestHeight - 1); + clip_pitch = -clip_pitch; + } + for (i = 0; i < m_DestHeight; i++) { + clip_scan[i] = *src_clip; + src_clip += clip_pitch; + } + } + DoCompose(m_pScanlineV, scanline, m_DestHeight, clip_scan, scan_extra_alpha, + m_pScanlineAlphaV); + src_scan = m_pScanlineV; + dest_scan = dest_buf; + for (i = 0; i < m_DestHeight; i++) { + for (int j = 0; j < Bpp; j++) { + dest_scan[j] = *src_scan++; + } + dest_scan += y_step; + } + src_alpha_scan = m_pScanlineAlphaV; + dest_alpha_scan = dest_alpha_buf; + if (dest_alpha_scan) { + for (i = 0; i < m_DestHeight; i++) { + *dest_alpha_scan = *src_alpha_scan++; + dest_alpha_scan += y_alpha_step; + } + } } diff --git a/core/src/fxge/dib/fx_dib_convert.cpp b/core/src/fxge/dib/fx_dib_convert.cpp index d7860aee19..74818f4a1b 100644 --- a/core/src/fxge/dib/fx_dib_convert.cpp +++ b/core/src/fxge/dib/fx_dib_convert.cpp @@ -50,8 +50,7 @@ const FX_DWORD g_dwWinPalette[256] = { 0xff00FF55, 0xff00FFAA, 0xff2A0000, 0xff2A0055, 0xff2A00AA, 0xff2A00FF, 0xff2A1F00, 0xff2A1F55, 0xff2A1FAA, 0xff2A1FFF, 0xff2A3F00, 0xff2A3F55, 0xffFFFBF0, 0xffA0A0A4, 0xff808080, 0xffFF0000, 0xff00FF00, 0xffFF0000, - 0xff0000FF, 0xffFF00FF, 0xff00FFFF, 0xffFFFFFF -}; + 0xff0000FF, 0xffFF00FF, 0xff00FFFF, 0xffFFFFFF}; const FX_DWORD g_dwMacPalette[256] = { 0xffFFFFFF, 0xffFFFFCC, 0xffFFFF99, 0xffFFFF66, 0xffFFFF33, 0xffFFFF00, 0xffFFCCFF, 0xffFFCCCC, 0xffFFCC99, 0xffFFCC66, 0xffFFCC33, 0xffFFCC00, @@ -88,989 +87,1160 @@ const FX_DWORD g_dwMacPalette[256] = { 0xff0099FF, 0xff0099CC, 0xff009999, 0xff009966, 0xff009933, 0xff009900, 0xff0066FF, 0xff0066CC, 0xff006699, 0xff006666, 0xff006633, 0xff006600, 0xff0033FF, 0xff0033CC, 0xff003399, 0xff003366, 0xff003333, 0xff003300, - 0xff0000FF, 0xff0000CC, 0xff000099, 0xff000066, 0xff000033, - 0xffEE0000, 0xffDD0000, 0xffBB0000, 0xffAA0000, 0xff880000, 0xff770000, - 0xff550000, 0xff440000, 0xff220000, 0xff110000, 0xff00EE00, 0xff00DD00, - 0xff00BB00, 0xff00AA00, 0xff008800, 0xff007700, 0xff005500, 0xff004400, - 0xff002200, 0xff001100, 0xff0000EE, 0xff0000DD, 0xff0000BB, 0xff0000AA, - 0xff000088, 0xff000077, 0xff000055, 0xff000044, 0xff000022, 0xff000011, - 0xffEEEEEE, 0xffDDDDDD, 0xffBBBBBB, 0xffAAAAAA, 0xff888888, 0xff777777, - 0xff555555, 0xff444444, 0xff222222, 0xff111111, 0xff000000 + 0xff0000FF, 0xff0000CC, 0xff000099, 0xff000066, 0xff000033, 0xffEE0000, + 0xffDD0000, 0xffBB0000, 0xffAA0000, 0xff880000, 0xff770000, 0xff550000, + 0xff440000, 0xff220000, 0xff110000, 0xff00EE00, 0xff00DD00, 0xff00BB00, + 0xff00AA00, 0xff008800, 0xff007700, 0xff005500, 0xff004400, 0xff002200, + 0xff001100, 0xff0000EE, 0xff0000DD, 0xff0000BB, 0xff0000AA, 0xff000088, + 0xff000077, 0xff000055, 0xff000044, 0xff000022, 0xff000011, 0xffEEEEEE, + 0xffDDDDDD, 0xffBBBBBB, 0xffAAAAAA, 0xff888888, 0xff777777, 0xff555555, + 0xff444444, 0xff222222, 0xff111111, 0xff000000}; +class CFX_Palette { + public: + CFX_Palette(); + ~CFX_Palette(); + + public: + FX_BOOL BuildPalette(const CFX_DIBSource* pBitmap, int dwPaletteType); + FX_DWORD* GetPalette() const { return m_pPalette; } + + FX_DWORD* GetColorLut() const { return m_cLut; } + FX_DWORD* GetAmountLut() const { return m_aLut; } + int32_t Getlut() const { return m_lut; } + + protected: + FX_DWORD* m_pPalette; + FX_DWORD* m_cLut; + FX_DWORD* m_aLut; + int m_lut; }; -class CFX_Palette -{ -public: - CFX_Palette(); - ~CFX_Palette(); -public: - FX_BOOL BuildPalette(const CFX_DIBSource* pBitmap, int dwPaletteType); - FX_DWORD* GetPalette() const - { - return m_pPalette; +int _Partition(FX_DWORD* alut, FX_DWORD* clut, int l, int r) { + FX_DWORD p_a = alut[l]; + FX_DWORD p_c = clut[l]; + while (l < r) { + while (l < r && alut[r] >= p_a) { + r--; } - - FX_DWORD* GetColorLut()const - { - return m_cLut; + if (l < r) { + alut[l] = alut[r]; + clut[l++] = clut[r]; } - FX_DWORD* GetAmountLut()const - { - return m_aLut; + while (l < r && alut[l] <= p_a) { + l++; } - int32_t Getlut()const - { - return m_lut; + if (l < r) { + alut[r] = alut[l]; + clut[r--] = clut[l]; } -protected: - FX_DWORD* m_pPalette; - FX_DWORD* m_cLut; - FX_DWORD* m_aLut; - int m_lut; -}; -int _Partition(FX_DWORD* alut, FX_DWORD* clut, int l, int r) -{ - FX_DWORD p_a = alut[l]; - FX_DWORD p_c = clut[l]; - while(l < r) { - while(l < r && alut[r] >= p_a) { - r--; - } - if (l < r) { - alut[l] = alut[r]; - clut[l++] = clut[r]; - } - while(l < r && alut[l] <= p_a) { - l++; - } - if (l < r) { - alut[r] = alut[l]; - clut[r--] = clut[l]; - } - } - alut[l] = p_a; - clut[l] = p_c; - return l; + } + alut[l] = p_a; + clut[l] = p_c; + return l; } -void _Qsort(FX_DWORD* alut, FX_DWORD* clut, int l, int r) -{ - if(l < r) { - int pI = _Partition(alut, clut, l, r); - _Qsort(alut, clut, l, pI - 1); - _Qsort(alut, clut, pI + 1, r); - } +void _Qsort(FX_DWORD* alut, FX_DWORD* clut, int l, int r) { + if (l < r) { + int pI = _Partition(alut, clut, l, r); + _Qsort(alut, clut, l, pI - 1); + _Qsort(alut, clut, pI + 1, r); + } } -void _ColorDecode(FX_DWORD pal_v, uint8_t& r, uint8_t& g, uint8_t& b) -{ - r = (uint8_t)((pal_v & 0xf00) >> 4); - g = (uint8_t)(pal_v & 0x0f0); - b = (uint8_t)((pal_v & 0x00f) << 4); +void _ColorDecode(FX_DWORD pal_v, uint8_t& r, uint8_t& g, uint8_t& b) { + r = (uint8_t)((pal_v & 0xf00) >> 4); + g = (uint8_t)(pal_v & 0x0f0); + b = (uint8_t)((pal_v & 0x00f) << 4); } -void _Obtain_Pal(FX_DWORD* aLut, FX_DWORD*cLut, FX_DWORD* dest_pal, int pal_type, FX_DWORD* win_mac_pal, FX_DWORD lut) -{ - int row, col; - FX_DWORD lut_1 = lut - 1; - if (pal_type == FXDIB_PALETTE_LOC) { - for (row = 0; row < 256; row++) { - int lut_offset = lut_1 - row; - if (lut_offset < 0) { - lut_offset += 256; - } - FX_DWORD color = cLut[lut_offset]; - uint8_t r, g, b; - _ColorDecode(color, r, g, b); - dest_pal[row] = ((FX_DWORD)r << 16) | ((FX_DWORD)g << 8) | b | 0xff000000; - aLut[lut_offset] = row; - } - } else { - for (row = 0; row < 256; row++) { - int lut_offset = lut_1 - row; - if (lut_offset < 0) { - lut_offset += 256; - } - uint8_t r, g, b; - _ColorDecode(cLut[lut_offset], r, g, b); - int error, min_error = 1000000; - int c_index = 0; - for (col = 0; col < 256; col++) { - FX_DWORD p_color = win_mac_pal[col]; - int d_r = r - (uint8_t)(p_color >> 16); - int d_g = g - (uint8_t)(p_color >> 8); - int d_b = b - (uint8_t)p_color; - error = d_r * d_r + d_g * d_g + d_b * d_b; - if (error < min_error) { - min_error = error; - c_index = col; - } - } - dest_pal[row] = win_mac_pal[c_index]; - aLut[lut_offset] = row; +void _Obtain_Pal(FX_DWORD* aLut, + FX_DWORD* cLut, + FX_DWORD* dest_pal, + int pal_type, + FX_DWORD* win_mac_pal, + FX_DWORD lut) { + int row, col; + FX_DWORD lut_1 = lut - 1; + if (pal_type == FXDIB_PALETTE_LOC) { + for (row = 0; row < 256; row++) { + int lut_offset = lut_1 - row; + if (lut_offset < 0) { + lut_offset += 256; + } + FX_DWORD color = cLut[lut_offset]; + uint8_t r, g, b; + _ColorDecode(color, r, g, b); + dest_pal[row] = ((FX_DWORD)r << 16) | ((FX_DWORD)g << 8) | b | 0xff000000; + aLut[lut_offset] = row; + } + } else { + for (row = 0; row < 256; row++) { + int lut_offset = lut_1 - row; + if (lut_offset < 0) { + lut_offset += 256; + } + uint8_t r, g, b; + _ColorDecode(cLut[lut_offset], r, g, b); + int error, min_error = 1000000; + int c_index = 0; + for (col = 0; col < 256; col++) { + FX_DWORD p_color = win_mac_pal[col]; + int d_r = r - (uint8_t)(p_color >> 16); + int d_g = g - (uint8_t)(p_color >> 8); + int d_b = b - (uint8_t)p_color; + error = d_r * d_r + d_g * d_g + d_b * d_b; + if (error < min_error) { + min_error = error; + c_index = col; } + } + dest_pal[row] = win_mac_pal[c_index]; + aLut[lut_offset] = row; } + } } -CFX_Palette::CFX_Palette() -{ - m_pPalette = NULL; +CFX_Palette::CFX_Palette() { + m_pPalette = NULL; + m_cLut = NULL; + m_aLut = NULL; + m_lut = 0; +} +CFX_Palette::~CFX_Palette() { + if (m_pPalette) { + FX_Free(m_pPalette); + } + if (m_cLut) { + FX_Free(m_cLut); + } + if (m_aLut) { + FX_Free(m_aLut); + } + m_lut = 0; +} +FX_BOOL CFX_Palette::BuildPalette(const CFX_DIBSource* pBitmap, int pal_type) { + if (pBitmap == NULL) { + return FALSE; + } + if (m_pPalette != NULL) { + FX_Free(m_pPalette); + } + m_pPalette = FX_Alloc(FX_DWORD, 256); + int bpp = pBitmap->GetBPP() / 8; + int width = pBitmap->GetWidth(); + int height = pBitmap->GetHeight(); + if (m_cLut) { + FX_Free(m_cLut); m_cLut = NULL; + } + if (m_aLut) { + FX_Free(m_aLut); m_aLut = NULL; - m_lut = 0; -} -CFX_Palette::~CFX_Palette() -{ - if (m_pPalette) { - FX_Free(m_pPalette); + } + m_cLut = FX_Alloc(FX_DWORD, 4096); + m_aLut = FX_Alloc(FX_DWORD, 4096); + int row, col; + m_lut = 0; + for (row = 0; row < height; row++) { + uint8_t* scan_line = (uint8_t*)pBitmap->GetScanline(row); + for (col = 0; col < width; col++) { + uint8_t* src_port = scan_line + col * bpp; + FX_DWORD b = src_port[0] & 0xf0; + FX_DWORD g = src_port[1] & 0xf0; + FX_DWORD r = src_port[2] & 0xf0; + FX_DWORD index = (r << 4) + g + (b >> 4); + m_aLut[index]++; } - if (m_cLut) { - FX_Free(m_cLut); + } + for (row = 0; row < 4096; row++) { + if (m_aLut[row] != 0) { + m_aLut[m_lut] = m_aLut[row]; + m_cLut[m_lut] = row; + m_lut++; } - if (m_aLut) { - FX_Free(m_aLut); - } - m_lut = 0; + } + _Qsort(m_aLut, m_cLut, 0, m_lut - 1); + FX_DWORD* win_mac_pal = NULL; + if (pal_type == FXDIB_PALETTE_WIN) { + win_mac_pal = (FX_DWORD*)g_dwWinPalette; + } else if (pal_type == FXDIB_PALETTE_MAC) { + win_mac_pal = (FX_DWORD*)g_dwMacPalette; + } + _Obtain_Pal(m_aLut, m_cLut, m_pPalette, pal_type, win_mac_pal, m_lut); + return TRUE; } -FX_BOOL CFX_Palette::BuildPalette(const CFX_DIBSource* pBitmap, int pal_type) -{ - if (pBitmap == NULL) { - return FALSE; - } - if (m_pPalette != NULL) { - FX_Free(m_pPalette); +FX_BOOL _ConvertBuffer_1bppMask2Gray(uint8_t* dest_buf, + int dest_pitch, + int width, + int height, + const CFX_DIBSource* pSrcBitmap, + int src_left, + int src_top) { + uint8_t set_gray, reset_gray; + set_gray = 0xff; + reset_gray = 0x00; + for (int row = 0; row < height; row++) { + uint8_t* dest_scan = dest_buf + row * dest_pitch; + FXSYS_memset(dest_scan, reset_gray, width); + const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row); + for (int col = src_left; col < src_left + width; col++) { + if (src_scan[col / 8] & (1 << (7 - col % 8))) { + *dest_scan = set_gray; + } + dest_scan++; } - m_pPalette = FX_Alloc(FX_DWORD, 256); - int bpp = pBitmap->GetBPP() / 8; - int width = pBitmap->GetWidth(); - int height = pBitmap->GetHeight(); - if (m_cLut) { - FX_Free(m_cLut); - m_cLut = NULL; + } + return TRUE; +} +FX_BOOL _ConvertBuffer_8bppMask2Gray(uint8_t* dest_buf, + int dest_pitch, + int width, + int height, + const CFX_DIBSource* pSrcBitmap, + int src_left, + int src_top) { + for (int row = 0; row < height; row++) { + uint8_t* dest_scan = dest_buf + row * dest_pitch; + const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left; + FXSYS_memcpy(dest_scan, src_scan, width); + } + return TRUE; +} +FX_BOOL _ConvertBuffer_1bppPlt2Gray(uint8_t* dest_buf, + int dest_pitch, + int width, + int height, + const CFX_DIBSource* pSrcBitmap, + int src_left, + int src_top, + void* pIccTransform) { + FX_DWORD* src_plt = pSrcBitmap->GetPalette(); + uint8_t gray[2]; + if (pIccTransform) { + FX_DWORD plt[2]; + if (pSrcBitmap->IsCmykImage()) { + plt[0] = FXCMYK_TODIB(src_plt[0]); + plt[1] = FXCMYK_TODIB(src_plt[1]); + } else { + uint8_t* bgr_ptr = (uint8_t*)plt; + bgr_ptr[0] = FXARGB_B(src_plt[0]); + bgr_ptr[1] = FXARGB_G(src_plt[0]); + bgr_ptr[2] = FXARGB_R(src_plt[0]); + bgr_ptr[3] = FXARGB_B(src_plt[1]); + bgr_ptr[4] = FXARGB_G(src_plt[1]); + bgr_ptr[5] = FXARGB_R(src_plt[1]); } - if (m_aLut) { - FX_Free(m_aLut); - m_aLut = NULL; + ICodec_IccModule* pIccModule = + CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + pIccModule->TranslateScanline(pIccTransform, gray, (const uint8_t*)plt, 2); + } else { + uint8_t reset_r, reset_g, reset_b, set_r, set_g, set_b; + if (pSrcBitmap->IsCmykImage()) { + AdobeCMYK_to_sRGB1( + FXSYS_GetCValue(src_plt[0]), FXSYS_GetMValue(src_plt[0]), + FXSYS_GetYValue(src_plt[0]), FXSYS_GetKValue(src_plt[0]), reset_r, + reset_g, reset_b); + AdobeCMYK_to_sRGB1(FXSYS_GetCValue(src_plt[1]), + FXSYS_GetMValue(src_plt[1]), + FXSYS_GetYValue(src_plt[1]), + FXSYS_GetKValue(src_plt[1]), set_r, set_g, set_b); + } else { + reset_r = FXARGB_R(src_plt[0]); + reset_g = FXARGB_G(src_plt[0]); + reset_b = FXARGB_B(src_plt[0]); + set_r = FXARGB_R(src_plt[1]); + set_g = FXARGB_G(src_plt[1]); + set_b = FXARGB_B(src_plt[1]); } - m_cLut = FX_Alloc(FX_DWORD, 4096); - m_aLut = FX_Alloc(FX_DWORD, 4096); - int row, col; - m_lut = 0; - for (row = 0; row < height; row++) { - uint8_t* scan_line = (uint8_t*)pBitmap->GetScanline(row); - for (col = 0; col < width; col++) { - uint8_t* src_port = scan_line + col * bpp; - FX_DWORD b = src_port[0] & 0xf0; - FX_DWORD g = src_port[1] & 0xf0; - FX_DWORD r = src_port[2] & 0xf0; - FX_DWORD index = (r << 4) + g + (b >> 4); - m_aLut[index]++; - } + gray[0] = FXRGB2GRAY(reset_r, reset_g, reset_b); + gray[1] = FXRGB2GRAY(set_r, set_g, set_b); + } + for (int row = 0; row < height; row++) { + uint8_t* dest_scan = dest_buf + row * dest_pitch; + FXSYS_memset(dest_scan, gray[0], width); + const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row); + for (int col = src_left; col < src_left + width; col++) { + if (src_scan[col / 8] & (1 << (7 - col % 8))) { + *dest_scan = gray[1]; + } + dest_scan++; } - for (row = 0; row < 4096; row++) { - if (m_aLut[row] != 0) { - m_aLut[m_lut] = m_aLut[row]; - m_cLut[m_lut] = row; - m_lut++; - } + } + return TRUE; +} +FX_BOOL _ConvertBuffer_8bppPlt2Gray(uint8_t* dest_buf, + int dest_pitch, + int width, + int height, + const CFX_DIBSource* pSrcBitmap, + int src_left, + int src_top, + void* pIccTransform) { + FX_DWORD* src_plt = pSrcBitmap->GetPalette(); + uint8_t gray[256]; + if (pIccTransform) { + FX_DWORD plt[256]; + if (pSrcBitmap->IsCmykImage()) { + for (int i = 0; i < 256; i++) { + plt[i] = FXCMYK_TODIB(src_plt[i]); + } + } else { + uint8_t* bgr_ptr = (uint8_t*)plt; + for (int i = 0; i < 256; i++) { + *bgr_ptr++ = FXARGB_B(src_plt[i]); + *bgr_ptr++ = FXARGB_G(src_plt[i]); + *bgr_ptr++ = FXARGB_R(src_plt[i]); + } } - _Qsort(m_aLut, m_cLut, 0, m_lut - 1); - FX_DWORD* win_mac_pal = NULL; - if (pal_type == FXDIB_PALETTE_WIN) { - win_mac_pal = (FX_DWORD*)g_dwWinPalette; - } else if (pal_type == FXDIB_PALETTE_MAC) { - win_mac_pal = (FX_DWORD*)g_dwMacPalette; + ICodec_IccModule* pIccModule = + CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + pIccModule->TranslateScanline(pIccTransform, gray, (const uint8_t*)plt, + 256); + } else { + if (pSrcBitmap->IsCmykImage()) { + uint8_t r, g, b; + for (int i = 0; i < 256; i++) { + AdobeCMYK_to_sRGB1( + FXSYS_GetCValue(src_plt[i]), FXSYS_GetMValue(src_plt[i]), + FXSYS_GetYValue(src_plt[i]), FXSYS_GetKValue(src_plt[i]), r, g, b); + gray[i] = FXRGB2GRAY(r, g, b); + } + } else + for (int i = 0; i < 256; i++) { + gray[i] = FXRGB2GRAY(FXARGB_R(src_plt[i]), FXARGB_G(src_plt[i]), + FXARGB_B(src_plt[i])); + } + } + for (int row = 0; row < height; row++) { + uint8_t* dest_scan = dest_buf + row * dest_pitch; + const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left; + for (int col = 0; col < width; col++) { + *dest_scan++ = gray[*src_scan++]; } - _Obtain_Pal(m_aLut, m_cLut, m_pPalette, pal_type, win_mac_pal, m_lut); - return TRUE; + } + return TRUE; } -FX_BOOL _ConvertBuffer_1bppMask2Gray(uint8_t* dest_buf, int dest_pitch, int width, int height, - const CFX_DIBSource* pSrcBitmap, int src_left, int src_top) -{ - uint8_t set_gray, reset_gray; - set_gray = 0xff; - reset_gray = 0x00; - for (int row = 0; row < height; row ++) { +FX_BOOL _ConvertBuffer_RgbOrCmyk2Gray(uint8_t* dest_buf, + int dest_pitch, + int width, + int height, + const CFX_DIBSource* pSrcBitmap, + int src_left, + int src_top, + void* pIccTransform) { + int Bpp = pSrcBitmap->GetBPP() / 8; + if (pIccTransform) { + ICodec_IccModule* pIccModule = + CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + if (Bpp == 3 || pSrcBitmap->IsCmykImage()) { + for (int row = 0; row < height; row++) { uint8_t* dest_scan = dest_buf + row * dest_pitch; - FXSYS_memset(dest_scan, reset_gray, width); - const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row); - for (int col = src_left; col < src_left + width; col ++) { - if (src_scan[col / 8] & (1 << (7 - col % 8))) { - *dest_scan = set_gray; - } - dest_scan ++; + const uint8_t* src_scan = + pSrcBitmap->GetScanline(src_top + row) + src_left * Bpp; + pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, + width); + } + } else { + for (int row = 0; row < height; row++) { + uint8_t* dest_scan = dest_buf + row * dest_pitch; + const uint8_t* src_scan = + pSrcBitmap->GetScanline(src_top + row) + src_left * 4; + for (int col = 0; col < width; col++) { + pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1); + dest_scan++; + src_scan += 4; } + } } - return TRUE; -} -FX_BOOL _ConvertBuffer_8bppMask2Gray(uint8_t* dest_buf, int dest_pitch, int width, int height, - const CFX_DIBSource* pSrcBitmap, int src_left, int src_top) -{ - for (int row = 0; row < height; row ++) { + } else { + if (pSrcBitmap->IsCmykImage()) { + for (int row = 0; row < height; row++) { uint8_t* dest_scan = dest_buf + row * dest_pitch; - const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left; - FXSYS_memcpy(dest_scan, src_scan, width); - } - return TRUE; -} -FX_BOOL _ConvertBuffer_1bppPlt2Gray(uint8_t* dest_buf, int dest_pitch, int width, int height, - const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform) -{ - FX_DWORD* src_plt = pSrcBitmap->GetPalette(); - uint8_t gray[2]; - if (pIccTransform) { - FX_DWORD plt[2]; - if (pSrcBitmap->IsCmykImage()) { - plt[0] = FXCMYK_TODIB(src_plt[0]); - plt[1] = FXCMYK_TODIB(src_plt[1]); - } else { - uint8_t* bgr_ptr = (uint8_t*)plt; - bgr_ptr[0] = FXARGB_B(src_plt[0]); - bgr_ptr[1] = FXARGB_G(src_plt[0]); - bgr_ptr[2] = FXARGB_R(src_plt[0]); - bgr_ptr[3] = FXARGB_B(src_plt[1]); - bgr_ptr[4] = FXARGB_G(src_plt[1]); - bgr_ptr[5] = FXARGB_R(src_plt[1]); + const uint8_t* src_scan = + pSrcBitmap->GetScanline(src_top + row) + src_left * 4; + for (int col = 0; col < width; col++) { + uint8_t r, g, b; + AdobeCMYK_to_sRGB1(FXSYS_GetCValue((FX_DWORD)src_scan[0]), + FXSYS_GetMValue((FX_DWORD)src_scan[1]), + FXSYS_GetYValue((FX_DWORD)src_scan[2]), + FXSYS_GetKValue((FX_DWORD)src_scan[3]), r, g, b); + *dest_scan++ = FXRGB2GRAY(r, g, b); + src_scan += 4; } - ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - pIccModule->TranslateScanline(pIccTransform, gray, (const uint8_t*)plt, 2); + } } else { - uint8_t reset_r, reset_g, reset_b, - set_r, set_g, set_b; - if (pSrcBitmap->IsCmykImage()) { - AdobeCMYK_to_sRGB1(FXSYS_GetCValue(src_plt[0]), FXSYS_GetMValue(src_plt[0]), FXSYS_GetYValue(src_plt[0]), FXSYS_GetKValue(src_plt[0]), - reset_r, reset_g, reset_b); - AdobeCMYK_to_sRGB1(FXSYS_GetCValue(src_plt[1]), FXSYS_GetMValue(src_plt[1]), FXSYS_GetYValue(src_plt[1]), FXSYS_GetKValue(src_plt[1]), - set_r, set_g, set_b); - } else { - reset_r = FXARGB_R(src_plt[0]); - reset_g = FXARGB_G(src_plt[0]); - reset_b = FXARGB_B(src_plt[0]); - set_r = FXARGB_R(src_plt[1]); - set_g = FXARGB_G(src_plt[1]); - set_b = FXARGB_B(src_plt[1]); - } - gray[0] = FXRGB2GRAY(reset_r, reset_g, reset_b); - gray[1] = FXRGB2GRAY(set_r, set_g, set_b); - } - for (int row = 0; row < height; row ++) { + for (int row = 0; row < height; row++) { uint8_t* dest_scan = dest_buf + row * dest_pitch; - FXSYS_memset(dest_scan, gray[0], width); - const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row); - for (int col = src_left; col < src_left + width; col ++) { - if (src_scan[col / 8] & (1 << (7 - col % 8))) { - *dest_scan = gray[1]; - } - dest_scan ++; + const uint8_t* src_scan = + pSrcBitmap->GetScanline(src_top + row) + src_left * Bpp; + for (int col = 0; col < width; col++) { + *dest_scan++ = FXRGB2GRAY(src_scan[2], src_scan[1], src_scan[0]); + src_scan += Bpp; } + } } - return TRUE; + } + return TRUE; } -FX_BOOL _ConvertBuffer_8bppPlt2Gray(uint8_t* dest_buf, int dest_pitch, int width, int height, - const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform) -{ - FX_DWORD* src_plt = pSrcBitmap->GetPalette(); - uint8_t gray[256]; - if (pIccTransform) { - FX_DWORD plt[256]; - if (pSrcBitmap->IsCmykImage()) { - for (int i = 0; i < 256; i ++) { - plt[i] = FXCMYK_TODIB(src_plt[i]); - } - } else { - uint8_t* bgr_ptr = (uint8_t*)plt; - for (int i = 0; i < 256; i ++) { - *bgr_ptr++ = FXARGB_B(src_plt[i]); - *bgr_ptr++ = FXARGB_G(src_plt[i]); - *bgr_ptr++ = FXARGB_R(src_plt[i]); - } +inline void _ConvertBuffer_IndexCopy(uint8_t* dest_buf, + int dest_pitch, + int width, + int height, + const CFX_DIBSource* pSrcBitmap, + int src_left, + int src_top) { + if (pSrcBitmap->GetBPP() == 1) { + for (int row = 0; row < height; row++) { + uint8_t* dest_scan = dest_buf + row * dest_pitch; + FXSYS_memset(dest_scan, 0, width); + const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row); + for (int col = src_left; col < src_left + width; col++) { + if (src_scan[col / 8] & (1 << (7 - col % 8))) { + *dest_scan = 1; } - ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - pIccModule->TranslateScanline(pIccTransform, gray, (const uint8_t*)plt, 256); - } else { - if (pSrcBitmap->IsCmykImage()) { - uint8_t r, g, b; - for (int i = 0; i < 256; i ++) { - AdobeCMYK_to_sRGB1(FXSYS_GetCValue(src_plt[i]), FXSYS_GetMValue(src_plt[i]), FXSYS_GetYValue(src_plt[i]), FXSYS_GetKValue(src_plt[i]), - r, g, b); - gray[i] = FXRGB2GRAY(r, g, b); - } - } else - for (int i = 0; i < 256; i ++) { - gray[i] = FXRGB2GRAY(FXARGB_R(src_plt[i]), FXARGB_G(src_plt[i]), FXARGB_B(src_plt[i])); - } + dest_scan++; + } } - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = dest_buf + row * dest_pitch; - const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left; - for (int col = 0; col < width; col ++) { - *dest_scan++ = gray[*src_scan++]; - } + } else { + for (int row = 0; row < height; row++) { + uint8_t* dest_scan = dest_buf + row * dest_pitch; + const uint8_t* src_scan = + pSrcBitmap->GetScanline(src_top + row) + src_left; + FXSYS_memcpy(dest_scan, src_scan, width); } - return TRUE; + } } -FX_BOOL _ConvertBuffer_RgbOrCmyk2Gray(uint8_t* dest_buf, int dest_pitch, int width, int height, - const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform) -{ - int Bpp = pSrcBitmap->GetBPP() / 8; - if (pIccTransform) { - ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - if (Bpp == 3 || pSrcBitmap->IsCmykImage()) { - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = dest_buf + row * dest_pitch; - const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * Bpp; - pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, width); - } - } else { - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = dest_buf + row * dest_pitch; - const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * 4; - for (int col = 0; col < width; col ++) { - pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1); - dest_scan++; - src_scan += 4; - } - } - } +FX_BOOL _ConvertBuffer_Plt2PltRgb8(uint8_t* dest_buf, + int dest_pitch, + int width, + int height, + const CFX_DIBSource* pSrcBitmap, + int src_left, + int src_top, + FX_DWORD* dst_plt, + void* pIccTransform) { + _ConvertBuffer_IndexCopy(dest_buf, dest_pitch, width, height, pSrcBitmap, + src_left, src_top); + FX_DWORD* src_plt = pSrcBitmap->GetPalette(); + int plt_size = pSrcBitmap->GetPaletteSize(); + if (pIccTransform) { + FX_DWORD plt[256]; + uint8_t* bgr_ptr = (uint8_t*)plt; + if (pSrcBitmap->IsCmykImage()) { + for (int i = 0; i < plt_size; i++) { + plt[i] = FXCMYK_TODIB(src_plt[i]); + } } else { - if (pSrcBitmap->IsCmykImage()) { - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = dest_buf + row * dest_pitch; - const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * 4; - for (int col = 0; col < width; col ++) { - uint8_t r, g, b; - AdobeCMYK_to_sRGB1(FXSYS_GetCValue((FX_DWORD)src_scan[0]), FXSYS_GetMValue((FX_DWORD)src_scan[1]), FXSYS_GetYValue((FX_DWORD)src_scan[2]), FXSYS_GetKValue((FX_DWORD)src_scan[3]), - r, g, b); - *dest_scan++ = FXRGB2GRAY(r, g, b); - src_scan += 4; - } - } - } else { - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = dest_buf + row * dest_pitch; - const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * Bpp; - for (int col = 0; col < width; col ++) { - *dest_scan++ = FXRGB2GRAY(src_scan[2], src_scan[1], src_scan[0]); - src_scan += Bpp; - } - } - } + for (int i = 0; i < plt_size; i++) { + *bgr_ptr++ = FXARGB_B(src_plt[i]); + *bgr_ptr++ = FXARGB_G(src_plt[i]); + *bgr_ptr++ = FXARGB_R(src_plt[i]); + } + bgr_ptr = (uint8_t*)plt; } - return TRUE; -} -inline void _ConvertBuffer_IndexCopy(uint8_t* dest_buf, int dest_pitch, int width, int height, - const CFX_DIBSource* pSrcBitmap, int src_left, int src_top) -{ - if (pSrcBitmap->GetBPP() == 1) { - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = dest_buf + row * dest_pitch; - FXSYS_memset(dest_scan, 0, width); - const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row); - for (int col = src_left; col < src_left + width; col ++) { - if (src_scan[col / 8] & (1 << (7 - col % 8))) { - *dest_scan = 1; - } - dest_scan ++; - } - } - } else { - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = dest_buf + row * dest_pitch; - const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left; - FXSYS_memcpy(dest_scan, src_scan, width); - } + ICodec_IccModule* pIccModule = + CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + pIccModule->TranslateScanline(pIccTransform, (uint8_t*)plt, + (const uint8_t*)plt, plt_size); + for (int i = 0; i < plt_size; i++) { + dst_plt[i] = FXARGB_MAKE(0xff, bgr_ptr[2], bgr_ptr[1], bgr_ptr[0]); + bgr_ptr += 3; } -} -FX_BOOL _ConvertBuffer_Plt2PltRgb8(uint8_t* dest_buf, int dest_pitch, int width, int height, - const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, FX_DWORD* dst_plt, void* pIccTransform) -{ - _ConvertBuffer_IndexCopy(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top); - FX_DWORD* src_plt = pSrcBitmap->GetPalette(); - int plt_size = pSrcBitmap->GetPaletteSize(); - if (pIccTransform) { - FX_DWORD plt[256]; - uint8_t* bgr_ptr = (uint8_t*)plt; - if (pSrcBitmap->IsCmykImage()) { - for (int i = 0; i < plt_size; i ++) { - plt[i] = FXCMYK_TODIB(src_plt[i]); - } - } else { - for (int i = 0; i < plt_size; i ++) { - *bgr_ptr++ = FXARGB_B(src_plt[i]); - *bgr_ptr++ = FXARGB_G(src_plt[i]); - *bgr_ptr++ = FXARGB_R(src_plt[i]); - } - bgr_ptr = (uint8_t*)plt; - } - ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - pIccModule->TranslateScanline(pIccTransform, (uint8_t*)plt, (const uint8_t*)plt, plt_size); - for (int i = 0; i < plt_size; i ++) { - dst_plt[i] = FXARGB_MAKE(0xff, bgr_ptr[2], bgr_ptr[1], bgr_ptr[0]); - bgr_ptr += 3; - } + } else { + if (pSrcBitmap->IsCmykImage()) { + for (int i = 0; i < plt_size; i++) { + uint8_t r, g, b; + AdobeCMYK_to_sRGB1( + FXSYS_GetCValue(src_plt[i]), FXSYS_GetMValue(src_plt[i]), + FXSYS_GetYValue(src_plt[i]), FXSYS_GetKValue(src_plt[i]), r, g, b); + dst_plt[i] = FXARGB_MAKE(0xff, r, g, b); + } } else { - if (pSrcBitmap->IsCmykImage()) { - for (int i = 0; i < plt_size; i ++) { - uint8_t r, g, b; - AdobeCMYK_to_sRGB1(FXSYS_GetCValue(src_plt[i]), FXSYS_GetMValue(src_plt[i]), FXSYS_GetYValue(src_plt[i]), FXSYS_GetKValue(src_plt[i]), - r, g, b); - dst_plt[i] = FXARGB_MAKE(0xff, r, g, b); - } - } else { - FXSYS_memcpy(dst_plt, src_plt, plt_size * 4); - } + FXSYS_memcpy(dst_plt, src_plt, plt_size * 4); } - return TRUE; + } + return TRUE; } -inline FX_BOOL _ConvertBuffer_Rgb2PltRgb8_NoTransform(uint8_t* dest_buf, int dest_pitch, int width, int height, - const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, FX_DWORD* dst_plt) -{ - int bpp = pSrcBitmap->GetBPP() / 8; - int row, col; - CFX_Palette palette; - palette.BuildPalette(pSrcBitmap, FXDIB_PALETTE_LOC); - FX_DWORD* cLut = palette.GetColorLut(); - FX_DWORD* aLut = palette.GetAmountLut(); - if (cLut == NULL || aLut == NULL) { - return FALSE; - } - int lut = palette.Getlut(); - FX_DWORD* pPalette = palette.GetPalette(); - if (lut > 256) { - int err, min_err; - int lut_256 = lut - 256; - for (row = 0; row < lut_256; row++) { - min_err = 1000000; - uint8_t r, g, b; - _ColorDecode(cLut[row], r, g, b); - int clrindex = 0; - for (int col = 0; col < 256; col++) { - FX_DWORD p_color = *(pPalette + col); - int d_r = r - (uint8_t)(p_color >> 16); - int d_g = g - (uint8_t)(p_color >> 8); - int d_b = b - (uint8_t)(p_color); - err = d_r * d_r + d_g * d_g + d_b * d_b; - if (err < min_err) { - min_err = err; - clrindex = col; - } - } - aLut[row] = clrindex; +inline FX_BOOL _ConvertBuffer_Rgb2PltRgb8_NoTransform( + uint8_t* dest_buf, + int dest_pitch, + int width, + int height, + const CFX_DIBSource* pSrcBitmap, + int src_left, + int src_top, + FX_DWORD* dst_plt) { + int bpp = pSrcBitmap->GetBPP() / 8; + int row, col; + CFX_Palette palette; + palette.BuildPalette(pSrcBitmap, FXDIB_PALETTE_LOC); + FX_DWORD* cLut = palette.GetColorLut(); + FX_DWORD* aLut = palette.GetAmountLut(); + if (cLut == NULL || aLut == NULL) { + return FALSE; + } + int lut = palette.Getlut(); + FX_DWORD* pPalette = palette.GetPalette(); + if (lut > 256) { + int err, min_err; + int lut_256 = lut - 256; + for (row = 0; row < lut_256; row++) { + min_err = 1000000; + uint8_t r, g, b; + _ColorDecode(cLut[row], r, g, b); + int clrindex = 0; + for (int col = 0; col < 256; col++) { + FX_DWORD p_color = *(pPalette + col); + int d_r = r - (uint8_t)(p_color >> 16); + int d_g = g - (uint8_t)(p_color >> 8); + int d_b = b - (uint8_t)(p_color); + err = d_r * d_r + d_g * d_g + d_b * d_b; + if (err < min_err) { + min_err = err; + clrindex = col; } + } + aLut[row] = clrindex; } - int32_t lut_1 = lut - 1; - for (row = 0; row < height; row ++) { - uint8_t* src_scan = (uint8_t*)pSrcBitmap->GetScanline(src_top + row) + src_left; - uint8_t* dest_scan = dest_buf + row * dest_pitch; - for (col = 0; col < width; col++) { - uint8_t* src_port = src_scan + col * bpp; - int r = src_port[2] & 0xf0; - int g = src_port[1] & 0xf0; - int b = src_port[0] & 0xf0; - FX_DWORD clrindex = (r << 4) + g + (b >> 4); - for (int i = lut_1; i >= 0; i--) - if (clrindex == cLut[i]) { - *(dest_scan + col) = (uint8_t)(aLut[i]); - break; - } + } + int32_t lut_1 = lut - 1; + for (row = 0; row < height; row++) { + uint8_t* src_scan = + (uint8_t*)pSrcBitmap->GetScanline(src_top + row) + src_left; + uint8_t* dest_scan = dest_buf + row * dest_pitch; + for (col = 0; col < width; col++) { + uint8_t* src_port = src_scan + col * bpp; + int r = src_port[2] & 0xf0; + int g = src_port[1] & 0xf0; + int b = src_port[0] & 0xf0; + FX_DWORD clrindex = (r << 4) + g + (b >> 4); + for (int i = lut_1; i >= 0; i--) + if (clrindex == cLut[i]) { + *(dest_scan + col) = (uint8_t)(aLut[i]); + break; } } - FXSYS_memcpy(dst_plt, pPalette, sizeof(FX_DWORD) * 256); - return TRUE; + } + FXSYS_memcpy(dst_plt, pPalette, sizeof(FX_DWORD) * 256); + return TRUE; } -FX_BOOL _ConvertBuffer_Rgb2PltRgb8(uint8_t* dest_buf, int dest_pitch, int width, int height, - const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, FX_DWORD* dst_plt, void* pIccTransform) -{ - FX_BOOL ret = _ConvertBuffer_Rgb2PltRgb8_NoTransform(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, dst_plt); - if (ret && pIccTransform) { - ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - for (int i = 0; i < 256; i++) { - FX_ARGB* plt = dst_plt + i; - FX_ARGB plt_entry = FXARGB_TODIB(*plt); - pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&plt_entry, (const uint8_t*)&plt_entry, 1); - *plt = FXARGB_TODIB(plt_entry); - } +FX_BOOL _ConvertBuffer_Rgb2PltRgb8(uint8_t* dest_buf, + int dest_pitch, + int width, + int height, + const CFX_DIBSource* pSrcBitmap, + int src_left, + int src_top, + FX_DWORD* dst_plt, + void* pIccTransform) { + FX_BOOL ret = _ConvertBuffer_Rgb2PltRgb8_NoTransform( + dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, + dst_plt); + if (ret && pIccTransform) { + ICodec_IccModule* pIccModule = + CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + for (int i = 0; i < 256; i++) { + FX_ARGB* plt = dst_plt + i; + FX_ARGB plt_entry = FXARGB_TODIB(*plt); + pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&plt_entry, + (const uint8_t*)&plt_entry, 1); + *plt = FXARGB_TODIB(plt_entry); } - return ret; + } + return ret; } -FX_BOOL _ConvertBuffer_1bppMask2Rgb(FXDIB_Format dst_format, uint8_t* dest_buf, int dest_pitch, int width, int height, - const CFX_DIBSource* pSrcBitmap, int src_left, int src_top) -{ - int comps = (dst_format & 0xff) / 8; - uint8_t set_gray, reset_gray; - set_gray = 0xff; - reset_gray = 0x00; - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = dest_buf + row * dest_pitch; - const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row); - for (int col = src_left; col < src_left + width; col ++) { - if (src_scan[col / 8] & (1 << (7 - col % 8))) { - dest_scan[0] = set_gray; - dest_scan[1] = set_gray; - dest_scan[2] = set_gray; - } else { - dest_scan[0] = reset_gray; - dest_scan[1] = reset_gray; - dest_scan[2] = reset_gray; - } - dest_scan += comps; - } +FX_BOOL _ConvertBuffer_1bppMask2Rgb(FXDIB_Format dst_format, + uint8_t* dest_buf, + int dest_pitch, + int width, + int height, + const CFX_DIBSource* pSrcBitmap, + int src_left, + int src_top) { + int comps = (dst_format & 0xff) / 8; + uint8_t set_gray, reset_gray; + set_gray = 0xff; + reset_gray = 0x00; + for (int row = 0; row < height; row++) { + uint8_t* dest_scan = dest_buf + row * dest_pitch; + const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row); + for (int col = src_left; col < src_left + width; col++) { + if (src_scan[col / 8] & (1 << (7 - col % 8))) { + dest_scan[0] = set_gray; + dest_scan[1] = set_gray; + dest_scan[2] = set_gray; + } else { + dest_scan[0] = reset_gray; + dest_scan[1] = reset_gray; + dest_scan[2] = reset_gray; + } + dest_scan += comps; } - return TRUE; + } + return TRUE; } -FX_BOOL _ConvertBuffer_8bppMask2Rgb(FXDIB_Format dst_format, uint8_t* dest_buf, int dest_pitch, int width, int height, - const CFX_DIBSource* pSrcBitmap, int src_left, int src_top) -{ - int comps = (dst_format & 0xff) / 8; - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = dest_buf + row * dest_pitch; - const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left; - uint8_t src_pixel; - for (int col = 0; col < width; col ++) { - src_pixel = *src_scan++; - *dest_scan++ = src_pixel; - *dest_scan++ = src_pixel; - *dest_scan = src_pixel; - dest_scan += comps - 2; - } +FX_BOOL _ConvertBuffer_8bppMask2Rgb(FXDIB_Format dst_format, + uint8_t* dest_buf, + int dest_pitch, + int width, + int height, + const CFX_DIBSource* pSrcBitmap, + int src_left, + int src_top) { + int comps = (dst_format & 0xff) / 8; + for (int row = 0; row < height; row++) { + uint8_t* dest_scan = dest_buf + row * dest_pitch; + const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left; + uint8_t src_pixel; + for (int col = 0; col < width; col++) { + src_pixel = *src_scan++; + *dest_scan++ = src_pixel; + *dest_scan++ = src_pixel; + *dest_scan = src_pixel; + dest_scan += comps - 2; } - return TRUE; + } + return TRUE; } -FX_BOOL _ConvertBuffer_1bppPlt2Rgb(FXDIB_Format dst_format, uint8_t* dest_buf, int dest_pitch, int width, int height, - const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform) -{ - int comps = (dst_format & 0xff) / 8; - FX_DWORD* src_plt = pSrcBitmap->GetPalette(); - FX_DWORD plt[2]; - uint8_t* bgr_ptr = (uint8_t*)plt; +FX_BOOL _ConvertBuffer_1bppPlt2Rgb(FXDIB_Format dst_format, + uint8_t* dest_buf, + int dest_pitch, + int width, + int height, + const CFX_DIBSource* pSrcBitmap, + int src_left, + int src_top, + void* pIccTransform) { + int comps = (dst_format & 0xff) / 8; + FX_DWORD* src_plt = pSrcBitmap->GetPalette(); + FX_DWORD plt[2]; + uint8_t* bgr_ptr = (uint8_t*)plt; + if (pSrcBitmap->IsCmykImage()) { + plt[0] = FXCMYK_TODIB(src_plt[0]); + plt[1] = FXCMYK_TODIB(src_plt[1]); + } else { + bgr_ptr[0] = FXARGB_B(src_plt[0]); + bgr_ptr[1] = FXARGB_G(src_plt[0]); + bgr_ptr[2] = FXARGB_R(src_plt[0]); + bgr_ptr[3] = FXARGB_B(src_plt[1]); + bgr_ptr[4] = FXARGB_G(src_plt[1]); + bgr_ptr[5] = FXARGB_R(src_plt[1]); + } + if (pIccTransform) { + ICodec_IccModule* pIccModule = + CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + pIccModule->TranslateScanline(pIccTransform, (uint8_t*)plt, + (const uint8_t*)plt, 2); + } else { if (pSrcBitmap->IsCmykImage()) { - plt[0] = FXCMYK_TODIB(src_plt[0]); - plt[1] = FXCMYK_TODIB(src_plt[1]); - } else { - bgr_ptr[0] = FXARGB_B(src_plt[0]); - bgr_ptr[1] = FXARGB_G(src_plt[0]); - bgr_ptr[2] = FXARGB_R(src_plt[0]); - bgr_ptr[3] = FXARGB_B(src_plt[1]); - bgr_ptr[4] = FXARGB_G(src_plt[1]); - bgr_ptr[5] = FXARGB_R(src_plt[1]); + AdobeCMYK_to_sRGB1( + FXSYS_GetCValue(src_plt[0]), FXSYS_GetMValue(src_plt[0]), + FXSYS_GetYValue(src_plt[0]), FXSYS_GetKValue(src_plt[0]), bgr_ptr[2], + bgr_ptr[1], bgr_ptr[0]); + AdobeCMYK_to_sRGB1( + FXSYS_GetCValue(src_plt[1]), FXSYS_GetMValue(src_plt[1]), + FXSYS_GetYValue(src_plt[1]), FXSYS_GetKValue(src_plt[1]), bgr_ptr[5], + bgr_ptr[4], bgr_ptr[3]); } - if (pIccTransform) { - ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - pIccModule->TranslateScanline(pIccTransform, (uint8_t*)plt, (const uint8_t*)plt, 2); - } else { - if (pSrcBitmap->IsCmykImage()) { - AdobeCMYK_to_sRGB1(FXSYS_GetCValue(src_plt[0]), FXSYS_GetMValue(src_plt[0]), FXSYS_GetYValue(src_plt[0]), FXSYS_GetKValue(src_plt[0]), - bgr_ptr[2], bgr_ptr[1], bgr_ptr[0]); - AdobeCMYK_to_sRGB1(FXSYS_GetCValue(src_plt[1]), FXSYS_GetMValue(src_plt[1]), FXSYS_GetYValue(src_plt[1]), FXSYS_GetKValue(src_plt[1]), - bgr_ptr[5], bgr_ptr[4], bgr_ptr[3]); - } + } + for (int row = 0; row < height; row++) { + uint8_t* dest_scan = dest_buf + row * dest_pitch; + const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row); + for (int col = src_left; col < src_left + width; col++) { + if (src_scan[col / 8] & (1 << (7 - col % 8))) { + *dest_scan++ = bgr_ptr[3]; + *dest_scan++ = bgr_ptr[4]; + *dest_scan = bgr_ptr[5]; + } else { + *dest_scan++ = bgr_ptr[0]; + *dest_scan++ = bgr_ptr[1]; + *dest_scan = bgr_ptr[2]; + } + dest_scan += comps - 2; } - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = dest_buf + row * dest_pitch; - const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row); - for (int col = src_left; col < src_left + width; col ++) { - if (src_scan[col / 8] & (1 << (7 - col % 8))) { - *dest_scan++ = bgr_ptr[3]; - *dest_scan++ = bgr_ptr[4]; - *dest_scan = bgr_ptr[5]; - } else { - *dest_scan++ = bgr_ptr[0]; - *dest_scan++ = bgr_ptr[1]; - *dest_scan = bgr_ptr[2]; - } - dest_scan += comps - 2; - } - } - return TRUE; + } + return TRUE; } -FX_BOOL _ConvertBuffer_8bppPlt2Rgb(FXDIB_Format dst_format, uint8_t* dest_buf, int dest_pitch, int width, int height, - const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform) -{ - int comps = (dst_format & 0xff) / 8; - FX_DWORD* src_plt = pSrcBitmap->GetPalette(); - FX_DWORD plt[256]; - uint8_t* bgr_ptr = (uint8_t*)plt; - if (!pSrcBitmap->IsCmykImage()) { - for (int i = 0; i < 256; i++) { - *bgr_ptr++ = FXARGB_B(src_plt[i]); - *bgr_ptr++ = FXARGB_G(src_plt[i]); - *bgr_ptr++ = FXARGB_R(src_plt[i]); - } - bgr_ptr = (uint8_t*)plt; +FX_BOOL _ConvertBuffer_8bppPlt2Rgb(FXDIB_Format dst_format, + uint8_t* dest_buf, + int dest_pitch, + int width, + int height, + const CFX_DIBSource* pSrcBitmap, + int src_left, + int src_top, + void* pIccTransform) { + int comps = (dst_format & 0xff) / 8; + FX_DWORD* src_plt = pSrcBitmap->GetPalette(); + FX_DWORD plt[256]; + uint8_t* bgr_ptr = (uint8_t*)plt; + if (!pSrcBitmap->IsCmykImage()) { + for (int i = 0; i < 256; i++) { + *bgr_ptr++ = FXARGB_B(src_plt[i]); + *bgr_ptr++ = FXARGB_G(src_plt[i]); + *bgr_ptr++ = FXARGB_R(src_plt[i]); } - if (pIccTransform) { - if (pSrcBitmap->IsCmykImage()) { - for (int i = 0; i < 256; i++) { - plt[i] = FXCMYK_TODIB(src_plt[i]); - } - } - ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - pIccModule->TranslateScanline(pIccTransform, (uint8_t*)plt, (const uint8_t*)plt, 256); - } else { - if (pSrcBitmap->IsCmykImage()) { - for (int i = 0; i < 256; i++) { - AdobeCMYK_to_sRGB1(FXSYS_GetCValue(src_plt[i]), FXSYS_GetMValue(src_plt[i]), FXSYS_GetYValue(src_plt[i]), FXSYS_GetKValue(src_plt[i]), - bgr_ptr[2], bgr_ptr[1], bgr_ptr[0]); - bgr_ptr += 3; - } - bgr_ptr = (uint8_t*)plt; - } + bgr_ptr = (uint8_t*)plt; + } + if (pIccTransform) { + if (pSrcBitmap->IsCmykImage()) { + for (int i = 0; i < 256; i++) { + plt[i] = FXCMYK_TODIB(src_plt[i]); + } } - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = dest_buf + row * dest_pitch; - const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left; - for (int col = 0; col < width; col ++) { - uint8_t* src_pixel = bgr_ptr + 3 * (*src_scan++); - *dest_scan++ = *src_pixel++; - *dest_scan++ = *src_pixel++; - *dest_scan = *src_pixel++; - dest_scan += comps - 2; - } + ICodec_IccModule* pIccModule = + CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + pIccModule->TranslateScanline(pIccTransform, (uint8_t*)plt, + (const uint8_t*)plt, 256); + } else { + if (pSrcBitmap->IsCmykImage()) { + for (int i = 0; i < 256; i++) { + AdobeCMYK_to_sRGB1( + FXSYS_GetCValue(src_plt[i]), FXSYS_GetMValue(src_plt[i]), + FXSYS_GetYValue(src_plt[i]), FXSYS_GetKValue(src_plt[i]), + bgr_ptr[2], bgr_ptr[1], bgr_ptr[0]); + bgr_ptr += 3; + } + bgr_ptr = (uint8_t*)plt; } - return TRUE; -} -FX_BOOL _ConvertBuffer_24bppRgb2Rgb24(uint8_t* dest_buf, int dest_pitch, int width, int height, - const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform) -{ - if (pIccTransform) { - ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = dest_buf + row * dest_pitch; - const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * 3; - pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, width); - } - } else { - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = dest_buf + row * dest_pitch; - const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * 3; - FXSYS_memcpy(dest_scan, src_scan, width * 3); - } + } + for (int row = 0; row < height; row++) { + uint8_t* dest_scan = dest_buf + row * dest_pitch; + const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left; + for (int col = 0; col < width; col++) { + uint8_t* src_pixel = bgr_ptr + 3 * (*src_scan++); + *dest_scan++ = *src_pixel++; + *dest_scan++ = *src_pixel++; + *dest_scan = *src_pixel++; + dest_scan += comps - 2; } - return TRUE; + } + return TRUE; } -FX_BOOL _ConvertBuffer_32bppRgb2Rgb24(uint8_t* dest_buf, int dest_pitch, int width, int height, - const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform) -{ - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = dest_buf + row * dest_pitch; - const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * 4; - for (int col = 0; col < width; col ++) { - *dest_scan++ = *src_scan++; - *dest_scan++ = *src_scan++; - *dest_scan++ = *src_scan++; - src_scan++; - } +FX_BOOL _ConvertBuffer_24bppRgb2Rgb24(uint8_t* dest_buf, + int dest_pitch, + int width, + int height, + const CFX_DIBSource* pSrcBitmap, + int src_left, + int src_top, + void* pIccTransform) { + if (pIccTransform) { + ICodec_IccModule* pIccModule = + CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + for (int row = 0; row < height; row++) { + uint8_t* dest_scan = dest_buf + row * dest_pitch; + const uint8_t* src_scan = + pSrcBitmap->GetScanline(src_top + row) + src_left * 3; + pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, width); } - if (pIccTransform) { - ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = dest_buf + row * dest_pitch; - pIccModule->TranslateScanline(pIccTransform, dest_scan, dest_scan, width); - } + } else { + for (int row = 0; row < height; row++) { + uint8_t* dest_scan = dest_buf + row * dest_pitch; + const uint8_t* src_scan = + pSrcBitmap->GetScanline(src_top + row) + src_left * 3; + FXSYS_memcpy(dest_scan, src_scan, width * 3); } - return TRUE; + } + return TRUE; } -FX_BOOL _ConvertBuffer_Rgb2Rgb32(uint8_t* dest_buf, int dest_pitch, int width, int height, - const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform) -{ - int comps = pSrcBitmap->GetBPP() / 8; - if (pIccTransform) { - ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = dest_buf + row * dest_pitch; - const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * comps; - for (int col = 0; col < width; col ++) { - pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1); - dest_scan += 4; - src_scan += comps; - } - } - } else { - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = dest_buf + row * dest_pitch; - const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * comps; - for (int col = 0; col < width; col ++) { - *dest_scan++ = *src_scan++; - *dest_scan++ = *src_scan++; - *dest_scan++ = *src_scan++; - dest_scan++; - src_scan += comps - 3; - } - } +FX_BOOL _ConvertBuffer_32bppRgb2Rgb24(uint8_t* dest_buf, + int dest_pitch, + int width, + int height, + const CFX_DIBSource* pSrcBitmap, + int src_left, + int src_top, + void* pIccTransform) { + for (int row = 0; row < height; row++) { + uint8_t* dest_scan = dest_buf + row * dest_pitch; + const uint8_t* src_scan = + pSrcBitmap->GetScanline(src_top + row) + src_left * 4; + for (int col = 0; col < width; col++) { + *dest_scan++ = *src_scan++; + *dest_scan++ = *src_scan++; + *dest_scan++ = *src_scan++; + src_scan++; } - return TRUE; -} -FX_BOOL _ConvertBuffer_32bppCmyk2Rgb32(uint8_t* dest_buf, int dest_pitch, int width, int height, - const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform) -{ - if (pIccTransform) { - ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = dest_buf + row * dest_pitch; - const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * 4; - for (int col = 0; col < width; col ++) { - pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1); - dest_scan += 4; - src_scan += 4; - } - } - } else { - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = dest_buf + row * dest_pitch; - const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * 4; - for (int col = 0; col < width; col ++) { - AdobeCMYK_to_sRGB1(src_scan[0], src_scan[1], src_scan[2], src_scan[3], - dest_scan[2], dest_scan[1], dest_scan[0]); - dest_scan += 4; - src_scan += 4; - } - } + } + if (pIccTransform) { + ICodec_IccModule* pIccModule = + CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + for (int row = 0; row < height; row++) { + uint8_t* dest_scan = dest_buf + row * dest_pitch; + pIccModule->TranslateScanline(pIccTransform, dest_scan, dest_scan, width); } - return TRUE; + } + return TRUE; } -FX_BOOL ConvertBuffer(FXDIB_Format dest_format, uint8_t* dest_buf, int dest_pitch, int width, int height, - const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, FX_DWORD*& d_pal, void* pIccTransform) -{ - FXDIB_Format src_format = pSrcBitmap->GetFormat(); - if (!CFX_GEModule::Get()->GetCodecModule() || !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) { - pIccTransform = NULL; +FX_BOOL _ConvertBuffer_Rgb2Rgb32(uint8_t* dest_buf, + int dest_pitch, + int width, + int height, + const CFX_DIBSource* pSrcBitmap, + int src_left, + int src_top, + void* pIccTransform) { + int comps = pSrcBitmap->GetBPP() / 8; + if (pIccTransform) { + ICodec_IccModule* pIccModule = + CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + for (int row = 0; row < height; row++) { + uint8_t* dest_scan = dest_buf + row * dest_pitch; + const uint8_t* src_scan = + pSrcBitmap->GetScanline(src_top + row) + src_left * comps; + for (int col = 0; col < width; col++) { + pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1); + dest_scan += 4; + src_scan += comps; + } } - switch (dest_format) { - case FXDIB_Invalid: - case FXDIB_1bppCmyk: - case FXDIB_1bppMask: - case FXDIB_1bppRgb: - ASSERT(FALSE); - return FALSE; - case FXDIB_8bppMask: { - if ((src_format & 0xff) == 1) { - if (pSrcBitmap->GetPalette()) { - return _ConvertBuffer_1bppPlt2Gray(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform); - } - return _ConvertBuffer_1bppMask2Gray(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top); - } - if ((src_format & 0xff) == 8) { - if (pSrcBitmap->GetPalette()) { - return _ConvertBuffer_8bppPlt2Gray(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform); - } - return _ConvertBuffer_8bppMask2Gray(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top); - } - if ((src_format & 0xff) >= 24) { - return _ConvertBuffer_RgbOrCmyk2Gray(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform); - } - return FALSE; - } - case FXDIB_8bppRgb: - case FXDIB_8bppRgba: { - if ((src_format & 0xff) == 8 && pSrcBitmap->GetPalette() == NULL) { - return ConvertBuffer(FXDIB_8bppMask, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, d_pal, pIccTransform); - } - d_pal = FX_Alloc(FX_DWORD, 256); - if (((src_format & 0xff) == 1 || (src_format & 0xff) == 8) && pSrcBitmap->GetPalette()) { - return _ConvertBuffer_Plt2PltRgb8(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, d_pal, pIccTransform); - } - if ((src_format & 0xff) >= 24) { - return _ConvertBuffer_Rgb2PltRgb8(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, d_pal, pIccTransform); - } - return FALSE; - } - case FXDIB_Rgb: - case FXDIB_Rgba: { - if ((src_format & 0xff) == 1) { - if (pSrcBitmap->GetPalette()) { - return _ConvertBuffer_1bppPlt2Rgb(dest_format, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform); - } - return _ConvertBuffer_1bppMask2Rgb(dest_format, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top); - } - if ((src_format & 0xff) == 8) { - if (pSrcBitmap->GetPalette()) { - return _ConvertBuffer_8bppPlt2Rgb(dest_format, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform); - } - return _ConvertBuffer_8bppMask2Rgb(dest_format, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top); - } - if ((src_format & 0xff) == 24) { - return _ConvertBuffer_24bppRgb2Rgb24(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform); - } - if ((src_format & 0xff) == 32) { - return _ConvertBuffer_32bppRgb2Rgb24(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform); - } - return FALSE; - } - case FXDIB_Argb: - case FXDIB_Rgb32: { - if ((src_format & 0xff) == 1) { - if (pSrcBitmap->GetPalette()) { - return _ConvertBuffer_1bppPlt2Rgb(dest_format, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform); - } - return _ConvertBuffer_1bppMask2Rgb(dest_format, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top); - } - if ((src_format & 0xff) == 8) { - if (pSrcBitmap->GetPalette()) { - return _ConvertBuffer_8bppPlt2Rgb(dest_format, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform); - } - return _ConvertBuffer_8bppMask2Rgb(dest_format, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top); - } - if ((src_format & 0xff) >= 24) { - if (src_format & 0x0400) { - return _ConvertBuffer_32bppCmyk2Rgb32(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform); - } - return _ConvertBuffer_Rgb2Rgb32(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform); - } - return FALSE; - } - default: - return FALSE; + } else { + for (int row = 0; row < height; row++) { + uint8_t* dest_scan = dest_buf + row * dest_pitch; + const uint8_t* src_scan = + pSrcBitmap->GetScanline(src_top + row) + src_left * comps; + for (int col = 0; col < width; col++) { + *dest_scan++ = *src_scan++; + *dest_scan++ = *src_scan++; + *dest_scan++ = *src_scan++; + dest_scan++; + src_scan += comps - 3; + } } - return FALSE; + } + return TRUE; } -CFX_DIBitmap* CFX_DIBSource::CloneConvert(FXDIB_Format dest_format, const FX_RECT* pClip, void* pIccTransform) const -{ - if(dest_format == GetFormat() && pIccTransform == NULL) { - return Clone(pClip); +FX_BOOL _ConvertBuffer_32bppCmyk2Rgb32(uint8_t* dest_buf, + int dest_pitch, + int width, + int height, + const CFX_DIBSource* pSrcBitmap, + int src_left, + int src_top, + void* pIccTransform) { + if (pIccTransform) { + ICodec_IccModule* pIccModule = + CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + for (int row = 0; row < height; row++) { + uint8_t* dest_scan = dest_buf + row * dest_pitch; + const uint8_t* src_scan = + pSrcBitmap->GetScanline(src_top + row) + src_left * 4; + for (int col = 0; col < width; col++) { + pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1); + dest_scan += 4; + src_scan += 4; + } + } + } else { + for (int row = 0; row < height; row++) { + uint8_t* dest_scan = dest_buf + row * dest_pitch; + const uint8_t* src_scan = + pSrcBitmap->GetScanline(src_top + row) + src_left * 4; + for (int col = 0; col < width; col++) { + AdobeCMYK_to_sRGB1(src_scan[0], src_scan[1], src_scan[2], src_scan[3], + dest_scan[2], dest_scan[1], dest_scan[0]); + dest_scan += 4; + src_scan += 4; + } } - if (pClip) { - CFX_DIBitmap* pClone = Clone(pClip); - if (pClone == NULL) { - return NULL; + } + return TRUE; +} +FX_BOOL ConvertBuffer(FXDIB_Format dest_format, + uint8_t* dest_buf, + int dest_pitch, + int width, + int height, + const CFX_DIBSource* pSrcBitmap, + int src_left, + int src_top, + FX_DWORD*& d_pal, + void* pIccTransform) { + FXDIB_Format src_format = pSrcBitmap->GetFormat(); + if (!CFX_GEModule::Get()->GetCodecModule() || + !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) { + pIccTransform = NULL; + } + switch (dest_format) { + case FXDIB_Invalid: + case FXDIB_1bppCmyk: + case FXDIB_1bppMask: + case FXDIB_1bppRgb: + ASSERT(FALSE); + return FALSE; + case FXDIB_8bppMask: { + if ((src_format & 0xff) == 1) { + if (pSrcBitmap->GetPalette()) { + return _ConvertBuffer_1bppPlt2Gray(dest_buf, dest_pitch, width, + height, pSrcBitmap, src_left, + src_top, pIccTransform); } - if(!pClone->ConvertFormat(dest_format, pIccTransform)) { - delete pClone; - return NULL; + return _ConvertBuffer_1bppMask2Gray(dest_buf, dest_pitch, width, height, + pSrcBitmap, src_left, src_top); + } + if ((src_format & 0xff) == 8) { + if (pSrcBitmap->GetPalette()) { + return _ConvertBuffer_8bppPlt2Gray(dest_buf, dest_pitch, width, + height, pSrcBitmap, src_left, + src_top, pIccTransform); } - return pClone; + return _ConvertBuffer_8bppMask2Gray(dest_buf, dest_pitch, width, height, + pSrcBitmap, src_left, src_top); + } + if ((src_format & 0xff) >= 24) { + return _ConvertBuffer_RgbOrCmyk2Gray(dest_buf, dest_pitch, width, + height, pSrcBitmap, src_left, + src_top, pIccTransform); + } + return FALSE; } - CFX_DIBitmap* pClone = new CFX_DIBitmap; - if(!pClone->Create(m_Width, m_Height, dest_format)) { - delete pClone; - return NULL; + case FXDIB_8bppRgb: + case FXDIB_8bppRgba: { + if ((src_format & 0xff) == 8 && pSrcBitmap->GetPalette() == NULL) { + return ConvertBuffer(FXDIB_8bppMask, dest_buf, dest_pitch, width, + height, pSrcBitmap, src_left, src_top, d_pal, + pIccTransform); + } + d_pal = FX_Alloc(FX_DWORD, 256); + if (((src_format & 0xff) == 1 || (src_format & 0xff) == 8) && + pSrcBitmap->GetPalette()) { + return _ConvertBuffer_Plt2PltRgb8(dest_buf, dest_pitch, width, height, + pSrcBitmap, src_left, src_top, d_pal, + pIccTransform); + } + if ((src_format & 0xff) >= 24) { + return _ConvertBuffer_Rgb2PltRgb8(dest_buf, dest_pitch, width, height, + pSrcBitmap, src_left, src_top, d_pal, + pIccTransform); + } + return FALSE; } - FX_BOOL ret = TRUE; - CFX_DIBitmap* pSrcAlpha = NULL; - if (m_AlphaFlag & 2) { - pSrcAlpha = (GetFormat() == FXDIB_Argb) ? GetAlphaMask() : m_pAlphaMask; - if (pSrcAlpha == NULL) { - delete pClone; - return NULL; + case FXDIB_Rgb: + case FXDIB_Rgba: { + if ((src_format & 0xff) == 1) { + if (pSrcBitmap->GetPalette()) { + return _ConvertBuffer_1bppPlt2Rgb(dest_format, dest_buf, dest_pitch, + width, height, pSrcBitmap, src_left, + src_top, pIccTransform); } + return _ConvertBuffer_1bppMask2Rgb(dest_format, dest_buf, dest_pitch, + width, height, pSrcBitmap, src_left, + src_top); + } + if ((src_format & 0xff) == 8) { + if (pSrcBitmap->GetPalette()) { + return _ConvertBuffer_8bppPlt2Rgb(dest_format, dest_buf, dest_pitch, + width, height, pSrcBitmap, src_left, + src_top, pIccTransform); + } + return _ConvertBuffer_8bppMask2Rgb(dest_format, dest_buf, dest_pitch, + width, height, pSrcBitmap, src_left, + src_top); + } + if ((src_format & 0xff) == 24) { + return _ConvertBuffer_24bppRgb2Rgb24(dest_buf, dest_pitch, width, + height, pSrcBitmap, src_left, + src_top, pIccTransform); + } + if ((src_format & 0xff) == 32) { + return _ConvertBuffer_32bppRgb2Rgb24(dest_buf, dest_pitch, width, + height, pSrcBitmap, src_left, + src_top, pIccTransform); + } + return FALSE; } - if (dest_format & 0x0200) { - if (dest_format == FXDIB_Argb) - ret = pSrcAlpha ? - pClone->LoadChannel(FXDIB_Alpha, pSrcAlpha, FXDIB_Alpha) : - pClone->LoadChannel(FXDIB_Alpha, 0xff); - else { - ret = pClone->CopyAlphaMask(pSrcAlpha); + case FXDIB_Argb: + case FXDIB_Rgb32: { + if ((src_format & 0xff) == 1) { + if (pSrcBitmap->GetPalette()) { + return _ConvertBuffer_1bppPlt2Rgb(dest_format, dest_buf, dest_pitch, + width, height, pSrcBitmap, src_left, + src_top, pIccTransform); + } + return _ConvertBuffer_1bppMask2Rgb(dest_format, dest_buf, dest_pitch, + width, height, pSrcBitmap, src_left, + src_top); + } + if ((src_format & 0xff) == 8) { + if (pSrcBitmap->GetPalette()) { + return _ConvertBuffer_8bppPlt2Rgb(dest_format, dest_buf, dest_pitch, + width, height, pSrcBitmap, src_left, + src_top, pIccTransform); } + return _ConvertBuffer_8bppMask2Rgb(dest_format, dest_buf, dest_pitch, + width, height, pSrcBitmap, src_left, + src_top); + } + if ((src_format & 0xff) >= 24) { + if (src_format & 0x0400) { + return _ConvertBuffer_32bppCmyk2Rgb32(dest_buf, dest_pitch, width, + height, pSrcBitmap, src_left, + src_top, pIccTransform); + } + return _ConvertBuffer_Rgb2Rgb32(dest_buf, dest_pitch, width, height, + pSrcBitmap, src_left, src_top, + pIccTransform); + } + return FALSE; } - if (pSrcAlpha && pSrcAlpha != m_pAlphaMask) { - delete pSrcAlpha; - pSrcAlpha = NULL; + default: + return FALSE; + } + return FALSE; +} +CFX_DIBitmap* CFX_DIBSource::CloneConvert(FXDIB_Format dest_format, + const FX_RECT* pClip, + void* pIccTransform) const { + if (dest_format == GetFormat() && pIccTransform == NULL) { + return Clone(pClip); + } + if (pClip) { + CFX_DIBitmap* pClone = Clone(pClip); + if (pClone == NULL) { + return NULL; } - if (!ret) { - delete pClone; - return NULL; + if (!pClone->ConvertFormat(dest_format, pIccTransform)) { + delete pClone; + return NULL; } - FX_DWORD* pal_8bpp = NULL; - ret = ConvertBuffer(dest_format, pClone->GetBuffer(), pClone->GetPitch(), m_Width, m_Height, this, 0, 0, pal_8bpp, pIccTransform); - if (!ret) { - if (pal_8bpp) { - FX_Free(pal_8bpp); - } - delete pClone; - return NULL; + return pClone; + } + CFX_DIBitmap* pClone = new CFX_DIBitmap; + if (!pClone->Create(m_Width, m_Height, dest_format)) { + delete pClone; + return NULL; + } + FX_BOOL ret = TRUE; + CFX_DIBitmap* pSrcAlpha = NULL; + if (m_AlphaFlag & 2) { + pSrcAlpha = (GetFormat() == FXDIB_Argb) ? GetAlphaMask() : m_pAlphaMask; + if (pSrcAlpha == NULL) { + delete pClone; + return NULL; } + } + if (dest_format & 0x0200) { + if (dest_format == FXDIB_Argb) + ret = pSrcAlpha ? pClone->LoadChannel(FXDIB_Alpha, pSrcAlpha, FXDIB_Alpha) + : pClone->LoadChannel(FXDIB_Alpha, 0xff); + else { + ret = pClone->CopyAlphaMask(pSrcAlpha); + } + } + if (pSrcAlpha && pSrcAlpha != m_pAlphaMask) { + delete pSrcAlpha; + pSrcAlpha = NULL; + } + if (!ret) { + delete pClone; + return NULL; + } + FX_DWORD* pal_8bpp = NULL; + ret = ConvertBuffer(dest_format, pClone->GetBuffer(), pClone->GetPitch(), + m_Width, m_Height, this, 0, 0, pal_8bpp, pIccTransform); + if (!ret) { if (pal_8bpp) { - pClone->CopyPalette(pal_8bpp); - FX_Free(pal_8bpp); - pal_8bpp = NULL; + FX_Free(pal_8bpp); } - return pClone; + delete pClone; + return NULL; + } + if (pal_8bpp) { + pClone->CopyPalette(pal_8bpp); + FX_Free(pal_8bpp); + pal_8bpp = NULL; + } + return pClone; } -FX_BOOL CFX_DIBitmap::ConvertFormat(FXDIB_Format dest_format, void* pIccTransform) -{ - FXDIB_Format src_format = GetFormat(); - if (dest_format == src_format && pIccTransform == NULL) { - return TRUE; - } - if (dest_format == FXDIB_8bppMask && src_format == FXDIB_8bppRgb && m_pPalette == NULL) { - m_AlphaFlag = 1; - return TRUE; +FX_BOOL CFX_DIBitmap::ConvertFormat(FXDIB_Format dest_format, + void* pIccTransform) { + FXDIB_Format src_format = GetFormat(); + if (dest_format == src_format && pIccTransform == NULL) { + return TRUE; + } + if (dest_format == FXDIB_8bppMask && src_format == FXDIB_8bppRgb && + m_pPalette == NULL) { + m_AlphaFlag = 1; + return TRUE; + } + if (dest_format == FXDIB_Argb && src_format == FXDIB_Rgb32 && + pIccTransform == NULL) { + m_AlphaFlag = 2; + for (int row = 0; row < m_Height; row++) { + uint8_t* scanline = m_pBuffer + row * m_Pitch + 3; + for (int col = 0; col < m_Width; col++) { + *scanline = 0xff; + scanline += 4; + } } - if (dest_format == FXDIB_Argb && src_format == FXDIB_Rgb32 && pIccTransform == NULL) { - m_AlphaFlag = 2; - for (int row = 0; row < m_Height; row ++) { - uint8_t* scanline = m_pBuffer + row * m_Pitch + 3; - for (int col = 0; col < m_Width; col ++) { - *scanline = 0xff; - scanline += 4; - } + return TRUE; + } + int dest_bpp = dest_format & 0xff; + int dest_pitch = (dest_bpp * m_Width + 31) / 32 * 4; + uint8_t* dest_buf = FX_TryAlloc(uint8_t, dest_pitch * m_Height + 4); + if (dest_buf == NULL) { + return FALSE; + } + CFX_DIBitmap* pAlphaMask = NULL; + if (dest_format == FXDIB_Argb) { + FXSYS_memset(dest_buf, 0xff, dest_pitch * m_Height + 4); + if (m_pAlphaMask) { + for (int row = 0; row < m_Height; row++) { + uint8_t* pDstScanline = dest_buf + row * dest_pitch + 3; + const uint8_t* pSrcScanline = m_pAlphaMask->GetScanline(row); + for (int col = 0; col < m_Width; col++) { + *pDstScanline = *pSrcScanline++; + pDstScanline += 4; } - return TRUE; + } } - int dest_bpp = dest_format & 0xff; - int dest_pitch = (dest_bpp * m_Width + 31) / 32 * 4; - uint8_t* dest_buf = FX_TryAlloc(uint8_t, dest_pitch * m_Height + 4); - if (dest_buf == NULL) { + } else if (dest_format & 0x0200) { + if (src_format == FXDIB_Argb) { + pAlphaMask = GetAlphaMask(); + if (pAlphaMask == NULL) { + FX_Free(dest_buf); return FALSE; - } - CFX_DIBitmap* pAlphaMask = NULL; - if (dest_format == FXDIB_Argb) { - FXSYS_memset(dest_buf, 0xff, dest_pitch * m_Height + 4); - if (m_pAlphaMask) { - for (int row = 0; row < m_Height; row ++) { - uint8_t* pDstScanline = dest_buf + row * dest_pitch + 3; - const uint8_t* pSrcScanline = m_pAlphaMask->GetScanline(row); - for (int col = 0; col < m_Width; col ++) { - *pDstScanline = *pSrcScanline++; - pDstScanline += 4; - } - } - } - } else if (dest_format & 0x0200) { - if (src_format == FXDIB_Argb) { - pAlphaMask = GetAlphaMask(); - if (pAlphaMask == NULL) { - FX_Free(dest_buf); - return FALSE; - } - } else { - if (m_pAlphaMask == NULL) { - if (!BuildAlphaMask()) { - FX_Free(dest_buf); - return FALSE; - } - pAlphaMask = m_pAlphaMask; - m_pAlphaMask = NULL; - } else { - pAlphaMask = m_pAlphaMask; - } + } + } else { + if (m_pAlphaMask == NULL) { + if (!BuildAlphaMask()) { + FX_Free(dest_buf); + return FALSE; } + pAlphaMask = m_pAlphaMask; + m_pAlphaMask = NULL; + } else { + pAlphaMask = m_pAlphaMask; + } } - FX_BOOL ret = FALSE; - FX_DWORD* pal_8bpp = NULL; - ret = ConvertBuffer(dest_format, dest_buf, dest_pitch, m_Width, m_Height, this, 0, 0, pal_8bpp, pIccTransform); - if (!ret) { - if (pal_8bpp) { - FX_Free(pal_8bpp); - } - if (pAlphaMask != m_pAlphaMask) { - delete pAlphaMask; - } - if (dest_buf) { - FX_Free(dest_buf); - } - return FALSE; - } - if (m_pAlphaMask && pAlphaMask != m_pAlphaMask) { - delete m_pAlphaMask; + } + FX_BOOL ret = FALSE; + FX_DWORD* pal_8bpp = NULL; + ret = ConvertBuffer(dest_format, dest_buf, dest_pitch, m_Width, m_Height, + this, 0, 0, pal_8bpp, pIccTransform); + if (!ret) { + if (pal_8bpp) { + FX_Free(pal_8bpp); } - m_pAlphaMask = pAlphaMask; - if (m_pPalette) { - FX_Free(m_pPalette); + if (pAlphaMask != m_pAlphaMask) { + delete pAlphaMask; } - m_pPalette = pal_8bpp; - if (!m_bExtBuf) { - FX_Free(m_pBuffer); + if (dest_buf) { + FX_Free(dest_buf); } - m_bExtBuf = FALSE; - m_pBuffer = dest_buf; - m_bpp = (uint8_t)dest_format; - m_AlphaFlag = (uint8_t)(dest_format >> 8); - m_Pitch = dest_pitch; - return TRUE; + return FALSE; + } + if (m_pAlphaMask && pAlphaMask != m_pAlphaMask) { + delete m_pAlphaMask; + } + m_pAlphaMask = pAlphaMask; + if (m_pPalette) { + FX_Free(m_pPalette); + } + m_pPalette = pal_8bpp; + if (!m_bExtBuf) { + FX_Free(m_pBuffer); + } + m_bExtBuf = FALSE; + m_pBuffer = dest_buf; + m_bpp = (uint8_t)dest_format; + m_AlphaFlag = (uint8_t)(dest_format >> 8); + m_Pitch = dest_pitch; + return TRUE; } diff --git a/core/src/fxge/dib/fx_dib_engine.cpp b/core/src/fxge/dib/fx_dib_engine.cpp index 7390c431d9..a91d99d935 100644 --- a/core/src/fxge/dib/fx_dib_engine.cpp +++ b/core/src/fxge/dib/fx_dib_engine.cpp @@ -9,827 +9,925 @@ #include "dib_int.h" #include extern int SDP_Table[513]; -void CWeightTable::Calc(int dest_len, int dest_min, int dest_max, int src_len, int src_min, int src_max, int flags) -{ - if (m_pWeightTables) { - FX_Free(m_pWeightTables); - m_pWeightTables = NULL; - } - double scale, base; - scale = FXSYS_Div((FX_FLOAT)(src_len), (FX_FLOAT)(dest_len)); - if (dest_len < 0) { - base = (FX_FLOAT)(src_len); - } else { - base = 0; - } - int ext_size = flags & FXDIB_BICUBIC_INTERPOL ? 3 : 1; - m_ItemSize = sizeof(int) * 2 + (int)(sizeof(int) * (FXSYS_ceil(FXSYS_fabs((FX_FLOAT)scale)) + ext_size)); - m_DestMin = dest_min; - if ((dest_max - dest_min) > (int)((1U << 30) - 4) / m_ItemSize) { - return; - } - m_pWeightTables = FX_TryAlloc(uint8_t, (dest_max - dest_min) * m_ItemSize + 4); - if (m_pWeightTables == NULL) { - return; - } - if ((flags & FXDIB_NOSMOOTH) != 0 || FXSYS_fabs((FX_FLOAT)scale) < 1.0f) { - for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel ++) { - PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel); - double src_pos = dest_pixel * scale + scale / 2 + base; - if (flags & FXDIB_INTERPOL) { - pixel_weights.m_SrcStart = (int)FXSYS_floor((FX_FLOAT)src_pos - 1.0f / 2); - pixel_weights.m_SrcEnd = (int)FXSYS_floor((FX_FLOAT)src_pos + 1.0f / 2); - if (pixel_weights.m_SrcStart < src_min) { - pixel_weights.m_SrcStart = src_min; - } - if (pixel_weights.m_SrcEnd >= src_max) { - pixel_weights.m_SrcEnd = src_max - 1; - } - if (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd) { - pixel_weights.m_Weights[0] = 65536; - } else { - pixel_weights.m_Weights[1] = FXSYS_round((FX_FLOAT)(src_pos - pixel_weights.m_SrcStart - 1.0f / 2) * 65536); - pixel_weights.m_Weights[0] = 65536 - pixel_weights.m_Weights[1]; - } - } else if (flags & FXDIB_BICUBIC_INTERPOL) { - pixel_weights.m_SrcStart = (int)FXSYS_floor((FX_FLOAT)src_pos - 1.0f / 2); - pixel_weights.m_SrcEnd = (int)FXSYS_floor((FX_FLOAT)src_pos + 1.0f / 2); - int start = pixel_weights.m_SrcStart - 1; - int end = pixel_weights.m_SrcEnd + 1; - if (start < src_min) { - start = src_min; - } - if (end >= src_max) { - end = src_max - 1; - } - if (pixel_weights.m_SrcStart < src_min) { - src_pos += src_min - pixel_weights.m_SrcStart; - pixel_weights.m_SrcStart = src_min; - } - if (pixel_weights.m_SrcEnd >= src_max) { - pixel_weights.m_SrcEnd = src_max - 1; - } - int weight; - weight = FXSYS_round((FX_FLOAT)(src_pos - pixel_weights.m_SrcStart - 1.0f / 2) * 256); - if (start == end) { - pixel_weights.m_Weights[0] = (SDP_Table[256 + weight] + SDP_Table[weight] + SDP_Table[256 - weight] + SDP_Table[512 - weight]) << 8; - } else if ((start == pixel_weights.m_SrcStart && (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd || - end == pixel_weights.m_SrcEnd) && start < end) || (start < pixel_weights.m_SrcStart && pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd && end == pixel_weights.m_SrcEnd)) { - if (start < pixel_weights.m_SrcStart) { - pixel_weights.m_Weights[0] = SDP_Table[256 + weight] << 8; - pixel_weights.m_Weights[1] = (SDP_Table[weight] + SDP_Table[256 - weight] + SDP_Table[512 - weight]) << 8; - } else { - if (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd) { - pixel_weights.m_Weights[0] = (SDP_Table[256 + weight] + SDP_Table[weight] + SDP_Table[256 - weight]) << 8; - pixel_weights.m_Weights[1] = SDP_Table[512 - weight] << 8; - } else { - pixel_weights.m_Weights[0] = (SDP_Table[256 + weight] + SDP_Table[weight]) << 8; - pixel_weights.m_Weights[1] = (SDP_Table[256 - weight] + SDP_Table[512 - weight]) << 8; - } - } - if (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd) { - pixel_weights.m_SrcEnd = end; - } - if (start < pixel_weights.m_SrcStart) { - pixel_weights.m_SrcStart = start; - } - } else if (start == pixel_weights.m_SrcStart && - start < pixel_weights.m_SrcEnd && - pixel_weights.m_SrcEnd < end) { - pixel_weights.m_Weights[0] = (SDP_Table[256 + weight] + SDP_Table[weight]) << 8; - pixel_weights.m_Weights[1] = SDP_Table[256 - weight] << 8; - pixel_weights.m_Weights[2] = SDP_Table[512 - weight] << 8; - pixel_weights.m_SrcEnd = end; - } else if (start < pixel_weights.m_SrcStart && - pixel_weights.m_SrcStart < pixel_weights.m_SrcEnd && - pixel_weights.m_SrcEnd == end) { - pixel_weights.m_Weights[0] = SDP_Table[256 + weight] << 8; - pixel_weights.m_Weights[1] = SDP_Table[weight] << 8; - pixel_weights.m_Weights[2] = (SDP_Table[256 - weight] + SDP_Table[512 - weight]) << 8; - pixel_weights.m_SrcStart = start; - } else { - pixel_weights.m_Weights[0] = SDP_Table[256 + weight] << 8; - pixel_weights.m_Weights[1] = SDP_Table[weight] << 8; - pixel_weights.m_Weights[2] = SDP_Table[256 - weight] << 8; - pixel_weights.m_Weights[3] = SDP_Table[512 - weight] << 8; - pixel_weights.m_SrcStart = start; - pixel_weights.m_SrcEnd = end; - } - } else { - pixel_weights.m_SrcStart = pixel_weights.m_SrcEnd = (int)FXSYS_floor((FX_FLOAT)src_pos); - if (pixel_weights.m_SrcStart < src_min) { - pixel_weights.m_SrcStart = src_min; - } - if (pixel_weights.m_SrcEnd >= src_max) { - pixel_weights.m_SrcEnd = src_max - 1; - } - pixel_weights.m_Weights[0] = 65536; - } +void CWeightTable::Calc(int dest_len, + int dest_min, + int dest_max, + int src_len, + int src_min, + int src_max, + int flags) { + if (m_pWeightTables) { + FX_Free(m_pWeightTables); + m_pWeightTables = NULL; + } + double scale, base; + scale = FXSYS_Div((FX_FLOAT)(src_len), (FX_FLOAT)(dest_len)); + if (dest_len < 0) { + base = (FX_FLOAT)(src_len); + } else { + base = 0; + } + int ext_size = flags & FXDIB_BICUBIC_INTERPOL ? 3 : 1; + m_ItemSize = + sizeof(int) * 2 + + (int)(sizeof(int) * (FXSYS_ceil(FXSYS_fabs((FX_FLOAT)scale)) + ext_size)); + m_DestMin = dest_min; + if ((dest_max - dest_min) > (int)((1U << 30) - 4) / m_ItemSize) { + return; + } + m_pWeightTables = + FX_TryAlloc(uint8_t, (dest_max - dest_min) * m_ItemSize + 4); + if (m_pWeightTables == NULL) { + return; + } + if ((flags & FXDIB_NOSMOOTH) != 0 || FXSYS_fabs((FX_FLOAT)scale) < 1.0f) { + for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel++) { + PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel); + double src_pos = dest_pixel * scale + scale / 2 + base; + if (flags & FXDIB_INTERPOL) { + pixel_weights.m_SrcStart = + (int)FXSYS_floor((FX_FLOAT)src_pos - 1.0f / 2); + pixel_weights.m_SrcEnd = (int)FXSYS_floor((FX_FLOAT)src_pos + 1.0f / 2); + if (pixel_weights.m_SrcStart < src_min) { + pixel_weights.m_SrcStart = src_min; } - return; - } - for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel ++) { - PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel); - double src_start = dest_pixel * scale + base; - double src_end = src_start + scale; - int start_i, end_i; - if (src_start < src_end) { - start_i = (int)FXSYS_floor((FX_FLOAT)src_start); - end_i = (int)FXSYS_ceil((FX_FLOAT)src_end); + if (pixel_weights.m_SrcEnd >= src_max) { + pixel_weights.m_SrcEnd = src_max - 1; + } + if (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd) { + pixel_weights.m_Weights[0] = 65536; } else { - start_i = (int)FXSYS_floor((FX_FLOAT)src_end); - end_i = (int)FXSYS_ceil((FX_FLOAT)src_start); + pixel_weights.m_Weights[1] = FXSYS_round( + (FX_FLOAT)(src_pos - pixel_weights.m_SrcStart - 1.0f / 2) * + 65536); + pixel_weights.m_Weights[0] = 65536 - pixel_weights.m_Weights[1]; } - if (start_i < src_min) { - start_i = src_min; + } else if (flags & FXDIB_BICUBIC_INTERPOL) { + pixel_weights.m_SrcStart = + (int)FXSYS_floor((FX_FLOAT)src_pos - 1.0f / 2); + pixel_weights.m_SrcEnd = (int)FXSYS_floor((FX_FLOAT)src_pos + 1.0f / 2); + int start = pixel_weights.m_SrcStart - 1; + int end = pixel_weights.m_SrcEnd + 1; + if (start < src_min) { + start = src_min; } - if (end_i >= src_max) { - end_i = src_max - 1; + if (end >= src_max) { + end = src_max - 1; } - if (start_i > end_i) { - if (start_i >= src_max) { - start_i = src_max - 1; - } - pixel_weights.m_SrcStart = start_i; - pixel_weights.m_SrcEnd = start_i; - continue; + if (pixel_weights.m_SrcStart < src_min) { + src_pos += src_min - pixel_weights.m_SrcStart; + pixel_weights.m_SrcStart = src_min; } - pixel_weights.m_SrcStart = start_i; - pixel_weights.m_SrcEnd = end_i; - for (int j = start_i; j <= end_i; j ++) { - double dest_start = FXSYS_Div((FX_FLOAT)(j) - base, scale); - double dest_end = FXSYS_Div((FX_FLOAT)(j + 1) - base, scale); - if (dest_start > dest_end) { - double temp = dest_start; - dest_start = dest_end; - dest_end = temp; - } - double area_start = dest_start > (FX_FLOAT)(dest_pixel) ? dest_start : (FX_FLOAT)(dest_pixel); - double area_end = dest_end > (FX_FLOAT)(dest_pixel + 1) ? (FX_FLOAT)(dest_pixel + 1) : dest_end; - double weight = area_start >= area_end ? 0.0f : area_end - area_start; - if (weight == 0 && j == end_i) { - pixel_weights.m_SrcEnd --; - break; + if (pixel_weights.m_SrcEnd >= src_max) { + pixel_weights.m_SrcEnd = src_max - 1; + } + int weight; + weight = FXSYS_round( + (FX_FLOAT)(src_pos - pixel_weights.m_SrcStart - 1.0f / 2) * 256); + if (start == end) { + pixel_weights.m_Weights[0] = + (SDP_Table[256 + weight] + SDP_Table[weight] + + SDP_Table[256 - weight] + SDP_Table[512 - weight]) + << 8; + } else if ((start == pixel_weights.m_SrcStart && + (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd || + end == pixel_weights.m_SrcEnd) && + start < end) || + (start < pixel_weights.m_SrcStart && + pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd && + end == pixel_weights.m_SrcEnd)) { + if (start < pixel_weights.m_SrcStart) { + pixel_weights.m_Weights[0] = SDP_Table[256 + weight] << 8; + pixel_weights.m_Weights[1] = + (SDP_Table[weight] + SDP_Table[256 - weight] + + SDP_Table[512 - weight]) + << 8; + } else { + if (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd) { + pixel_weights.m_Weights[0] = + (SDP_Table[256 + weight] + SDP_Table[weight] + + SDP_Table[256 - weight]) + << 8; + pixel_weights.m_Weights[1] = SDP_Table[512 - weight] << 8; + } else { + pixel_weights.m_Weights[0] = + (SDP_Table[256 + weight] + SDP_Table[weight]) << 8; + pixel_weights.m_Weights[1] = + (SDP_Table[256 - weight] + SDP_Table[512 - weight]) << 8; } - pixel_weights.m_Weights[j - start_i] = FXSYS_round((FX_FLOAT)(weight * 65536)); + } + if (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd) { + pixel_weights.m_SrcEnd = end; + } + if (start < pixel_weights.m_SrcStart) { + pixel_weights.m_SrcStart = start; + } + } else if (start == pixel_weights.m_SrcStart && + start < pixel_weights.m_SrcEnd && + pixel_weights.m_SrcEnd < end) { + pixel_weights.m_Weights[0] = + (SDP_Table[256 + weight] + SDP_Table[weight]) << 8; + pixel_weights.m_Weights[1] = SDP_Table[256 - weight] << 8; + pixel_weights.m_Weights[2] = SDP_Table[512 - weight] << 8; + pixel_weights.m_SrcEnd = end; + } else if (start < pixel_weights.m_SrcStart && + pixel_weights.m_SrcStart < pixel_weights.m_SrcEnd && + pixel_weights.m_SrcEnd == end) { + pixel_weights.m_Weights[0] = SDP_Table[256 + weight] << 8; + pixel_weights.m_Weights[1] = SDP_Table[weight] << 8; + pixel_weights.m_Weights[2] = + (SDP_Table[256 - weight] + SDP_Table[512 - weight]) << 8; + pixel_weights.m_SrcStart = start; + } else { + pixel_weights.m_Weights[0] = SDP_Table[256 + weight] << 8; + pixel_weights.m_Weights[1] = SDP_Table[weight] << 8; + pixel_weights.m_Weights[2] = SDP_Table[256 - weight] << 8; + pixel_weights.m_Weights[3] = SDP_Table[512 - weight] << 8; + pixel_weights.m_SrcStart = start; + pixel_weights.m_SrcEnd = end; } - } + } else { + pixel_weights.m_SrcStart = pixel_weights.m_SrcEnd = + (int)FXSYS_floor((FX_FLOAT)src_pos); + if (pixel_weights.m_SrcStart < src_min) { + pixel_weights.m_SrcStart = src_min; + } + if (pixel_weights.m_SrcEnd >= src_max) { + pixel_weights.m_SrcEnd = src_max - 1; + } + pixel_weights.m_Weights[0] = 65536; + } + } + return; + } + for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel++) { + PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel); + double src_start = dest_pixel * scale + base; + double src_end = src_start + scale; + int start_i, end_i; + if (src_start < src_end) { + start_i = (int)FXSYS_floor((FX_FLOAT)src_start); + end_i = (int)FXSYS_ceil((FX_FLOAT)src_end); + } else { + start_i = (int)FXSYS_floor((FX_FLOAT)src_end); + end_i = (int)FXSYS_ceil((FX_FLOAT)src_start); + } + if (start_i < src_min) { + start_i = src_min; + } + if (end_i >= src_max) { + end_i = src_max - 1; + } + if (start_i > end_i) { + if (start_i >= src_max) { + start_i = src_max - 1; + } + pixel_weights.m_SrcStart = start_i; + pixel_weights.m_SrcEnd = start_i; + continue; + } + pixel_weights.m_SrcStart = start_i; + pixel_weights.m_SrcEnd = end_i; + for (int j = start_i; j <= end_i; j++) { + double dest_start = FXSYS_Div((FX_FLOAT)(j)-base, scale); + double dest_end = FXSYS_Div((FX_FLOAT)(j + 1) - base, scale); + if (dest_start > dest_end) { + double temp = dest_start; + dest_start = dest_end; + dest_end = temp; + } + double area_start = dest_start > (FX_FLOAT)(dest_pixel) + ? dest_start + : (FX_FLOAT)(dest_pixel); + double area_end = dest_end > (FX_FLOAT)(dest_pixel + 1) + ? (FX_FLOAT)(dest_pixel + 1) + : dest_end; + double weight = area_start >= area_end ? 0.0f : area_end - area_start; + if (weight == 0 && j == end_i) { + pixel_weights.m_SrcEnd--; + break; + } + pixel_weights.m_Weights[j - start_i] = + FXSYS_round((FX_FLOAT)(weight * 65536)); + } + } } -CStretchEngine::CStretchEngine(IFX_ScanlineComposer* pDestBitmap, FXDIB_Format dest_format, - int dest_width, int dest_height, const FX_RECT& clip_rect, - const CFX_DIBSource* pSrcBitmap, int flags) -{ - m_State = 0; - m_DestFormat = dest_format; - m_DestBpp = dest_format & 0xff; - m_SrcBpp = pSrcBitmap->GetFormat() & 0xff; - m_bHasAlpha = pSrcBitmap->GetFormat() & 0x200; - m_pSrcPalette = pSrcBitmap->GetPalette(); - m_pDestBitmap = pDestBitmap; - m_DestWidth = dest_width; - m_DestHeight = dest_height; - m_pInterBuf = NULL; - m_pExtraAlphaBuf = NULL; - m_pDestMaskScanline = NULL; - m_DestClip = clip_rect; - FX_DWORD size = clip_rect.Width(); - if (size && m_DestBpp > (int)(INT_MAX / size)) { - return; +CStretchEngine::CStretchEngine(IFX_ScanlineComposer* pDestBitmap, + FXDIB_Format dest_format, + int dest_width, + int dest_height, + const FX_RECT& clip_rect, + const CFX_DIBSource* pSrcBitmap, + int flags) { + m_State = 0; + m_DestFormat = dest_format; + m_DestBpp = dest_format & 0xff; + m_SrcBpp = pSrcBitmap->GetFormat() & 0xff; + m_bHasAlpha = pSrcBitmap->GetFormat() & 0x200; + m_pSrcPalette = pSrcBitmap->GetPalette(); + m_pDestBitmap = pDestBitmap; + m_DestWidth = dest_width; + m_DestHeight = dest_height; + m_pInterBuf = NULL; + m_pExtraAlphaBuf = NULL; + m_pDestMaskScanline = NULL; + m_DestClip = clip_rect; + FX_DWORD size = clip_rect.Width(); + if (size && m_DestBpp > (int)(INT_MAX / size)) { + return; + } + size *= m_DestBpp; + if (size > INT_MAX - 31) { + return; + } + size += 31; + size = size / 32 * 4; + m_pDestScanline = FX_TryAlloc(uint8_t, size); + if (m_pDestScanline == NULL) { + return; + } + if (dest_format == FXDIB_Rgb32) { + FXSYS_memset(m_pDestScanline, 255, size); + } + m_InterPitch = (m_DestClip.Width() * m_DestBpp + 31) / 32 * 4; + m_ExtraMaskPitch = (m_DestClip.Width() * 8 + 31) / 32 * 4; + m_pInterBuf = NULL; + m_pSource = pSrcBitmap; + m_SrcWidth = pSrcBitmap->GetWidth(); + m_SrcHeight = pSrcBitmap->GetHeight(); + m_SrcPitch = (m_SrcWidth * m_SrcBpp + 31) / 32 * 4; + if ((flags & FXDIB_NOSMOOTH) == 0) { + FX_BOOL bInterpol = + flags & FXDIB_INTERPOL || flags & FXDIB_BICUBIC_INTERPOL; + if (!bInterpol && FXSYS_abs(dest_width) != 0 && + FXSYS_abs(dest_height) < + m_SrcWidth * m_SrcHeight * 8 / FXSYS_abs(dest_width)) { + flags = FXDIB_INTERPOL; } - size *= m_DestBpp; - if (size > INT_MAX - 31) { - return; - } - size += 31; - size = size / 32 * 4; - m_pDestScanline = FX_TryAlloc(uint8_t, size); - if (m_pDestScanline == NULL) { - return; - } - if (dest_format == FXDIB_Rgb32) { - FXSYS_memset(m_pDestScanline, 255, size); + m_Flags = flags; + } else { + m_Flags = FXDIB_NOSMOOTH; + if (flags & FXDIB_DOWNSAMPLE) { + m_Flags |= FXDIB_DOWNSAMPLE; + } + } + double scale_x = FXSYS_Div((FX_FLOAT)(m_SrcWidth), (FX_FLOAT)(m_DestWidth)); + double scale_y = FXSYS_Div((FX_FLOAT)(m_SrcHeight), (FX_FLOAT)(m_DestHeight)); + double base_x = m_DestWidth > 0 ? 0.0f : (FX_FLOAT)(m_DestWidth); + double base_y = m_DestHeight > 0 ? 0.0f : (FX_FLOAT)(m_DestHeight); + double src_left = FXSYS_Mul(scale_x, (FX_FLOAT)(clip_rect.left) + base_x); + double src_right = FXSYS_Mul(scale_x, (FX_FLOAT)(clip_rect.right) + base_x); + double src_top = FXSYS_Mul(scale_y, (FX_FLOAT)(clip_rect.top) + base_y); + double src_bottom = FXSYS_Mul(scale_y, (FX_FLOAT)(clip_rect.bottom) + base_y); + if (src_left > src_right) { + double temp = src_left; + src_left = src_right; + src_right = temp; + } + if (src_top > src_bottom) { + double temp = src_top; + src_top = src_bottom; + src_bottom = temp; + } + m_SrcClip.left = (int)FXSYS_floor((FX_FLOAT)src_left); + m_SrcClip.right = (int)FXSYS_ceil((FX_FLOAT)src_right); + m_SrcClip.top = (int)FXSYS_floor((FX_FLOAT)src_top); + m_SrcClip.bottom = (int)FXSYS_ceil((FX_FLOAT)src_bottom); + FX_RECT src_rect(0, 0, m_SrcWidth, m_SrcHeight); + m_SrcClip.Intersect(src_rect); + if (m_SrcBpp == 1) { + if (m_DestBpp == 8) { + m_TransMethod = 1; + } else { + m_TransMethod = 2; + } + } else if (m_SrcBpp == 8) { + if (m_DestBpp == 8) { + if (!m_bHasAlpha) { + m_TransMethod = 3; + } else { + m_TransMethod = 4; + } + } else { + if (!m_bHasAlpha) { + m_TransMethod = 5; + } else { + m_TransMethod = 6; + } + } + } else { + if (!m_bHasAlpha) { + m_TransMethod = 7; + } else { + m_TransMethod = 8; } - m_InterPitch = (m_DestClip.Width() * m_DestBpp + 31) / 32 * 4; - m_ExtraMaskPitch = (m_DestClip.Width() * 8 + 31) / 32 * 4; - m_pInterBuf = NULL; - m_pSource = pSrcBitmap; - m_SrcWidth = pSrcBitmap->GetWidth(); - m_SrcHeight = pSrcBitmap->GetHeight(); - m_SrcPitch = (m_SrcWidth * m_SrcBpp + 31) / 32 * 4; - if ((flags & FXDIB_NOSMOOTH) == 0) { - FX_BOOL bInterpol = flags & FXDIB_INTERPOL || flags & FXDIB_BICUBIC_INTERPOL; - if (!bInterpol && FXSYS_abs(dest_width) != 0 && FXSYS_abs(dest_height) < m_SrcWidth * m_SrcHeight * 8 / FXSYS_abs(dest_width)) { - flags = FXDIB_INTERPOL; + } +} +FX_BOOL CStretchEngine::Continue(IFX_Pause* pPause) { + while (m_State == 1) { + if (ContinueStretchHorz(pPause)) { + return TRUE; + } + m_State = 2; + StretchVert(); + } + return FALSE; +} +CStretchEngine::~CStretchEngine() { + if (m_pDestScanline) { + FX_Free(m_pDestScanline); + } + if (m_pInterBuf) { + FX_Free(m_pInterBuf); + } + if (m_pExtraAlphaBuf) { + FX_Free(m_pExtraAlphaBuf); + } + if (m_pDestMaskScanline) { + FX_Free(m_pDestMaskScanline); + } +} +FX_BOOL CStretchEngine::StartStretchHorz() { + if (m_DestWidth == 0 || m_pDestScanline == NULL || + m_SrcClip.Height() > (int)((1U << 29) / m_InterPitch) || + m_SrcClip.Height() == 0) { + return FALSE; + } + m_pInterBuf = FX_TryAlloc(unsigned char, m_SrcClip.Height() * m_InterPitch); + if (m_pInterBuf == NULL) { + return FALSE; + } + if (m_pSource && m_bHasAlpha && m_pSource->m_pAlphaMask) { + m_pExtraAlphaBuf = + FX_Alloc2D(unsigned char, m_SrcClip.Height(), m_ExtraMaskPitch); + FX_DWORD size = (m_DestClip.Width() * 8 + 31) / 32 * 4; + m_pDestMaskScanline = FX_TryAlloc(unsigned char, size); + if (!m_pDestMaskScanline) { + return FALSE; + } + } + m_WeightTable.Calc(m_DestWidth, m_DestClip.left, m_DestClip.right, m_SrcWidth, + m_SrcClip.left, m_SrcClip.right, m_Flags); + if (m_WeightTable.m_pWeightTables == NULL) { + return FALSE; + } + m_CurRow = m_SrcClip.top; + m_State = 1; + return TRUE; +} +#define FX_STRECH_PAUSE_ROWS 10 +FX_BOOL CStretchEngine::ContinueStretchHorz(IFX_Pause* pPause) { + if (!m_DestWidth) { + return 0; + } + if (m_pSource->SkipToScanline(m_CurRow, pPause)) { + return TRUE; + } + int Bpp = m_DestBpp / 8; + int rows_to_go = FX_STRECH_PAUSE_ROWS; + for (; m_CurRow < m_SrcClip.bottom; m_CurRow++) { + if (rows_to_go == 0) { + if (pPause && pPause->NeedToPauseNow()) { + return TRUE; + } + rows_to_go = FX_STRECH_PAUSE_ROWS; + } + const uint8_t* src_scan = m_pSource->GetScanline(m_CurRow); + uint8_t* dest_scan = + m_pInterBuf + (m_CurRow - m_SrcClip.top) * m_InterPitch; + const uint8_t* src_scan_mask = NULL; + uint8_t* dest_scan_mask = NULL; + if (m_pExtraAlphaBuf) { + src_scan_mask = m_pSource->m_pAlphaMask->GetScanline(m_CurRow); + dest_scan_mask = + m_pExtraAlphaBuf + (m_CurRow - m_SrcClip.top) * m_ExtraMaskPitch; + } + switch (m_TransMethod) { + case 1: + case 2: { + for (int col = m_DestClip.left; col < m_DestClip.right; col++) { + PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); + int dest_a = 0; + for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; + j++) { + int pixel_weight = + pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; + if (src_scan[j / 8] & (1 << (7 - j % 8))) { + dest_a += pixel_weight * 255; + } + } + if (m_Flags & FXDIB_BICUBIC_INTERPOL) { + dest_a = dest_a < 0 ? 0 : dest_a > 16711680 ? 16711680 : dest_a; + } + *dest_scan++ = (uint8_t)(dest_a >> 16); } - m_Flags = flags; - } else { - m_Flags = FXDIB_NOSMOOTH; - if (flags & FXDIB_DOWNSAMPLE) { - m_Flags |= FXDIB_DOWNSAMPLE; + break; + } + case 3: { + for (int col = m_DestClip.left; col < m_DestClip.right; col++) { + PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); + int dest_a = 0; + for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; + j++) { + int pixel_weight = + pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; + dest_a += pixel_weight * src_scan[j]; + } + if (m_Flags & FXDIB_BICUBIC_INTERPOL) { + dest_a = dest_a < 0 ? 0 : dest_a > 16711680 ? 16711680 : dest_a; + } + *dest_scan++ = (uint8_t)(dest_a >> 16); } - } - double scale_x = FXSYS_Div((FX_FLOAT)(m_SrcWidth), (FX_FLOAT)(m_DestWidth)); - double scale_y = FXSYS_Div((FX_FLOAT)(m_SrcHeight), (FX_FLOAT)(m_DestHeight)); - double base_x = m_DestWidth > 0 ? 0.0f : (FX_FLOAT)(m_DestWidth); - double base_y = m_DestHeight > 0 ? 0.0f : (FX_FLOAT)(m_DestHeight); - double src_left = FXSYS_Mul(scale_x, (FX_FLOAT)(clip_rect.left) + base_x); - double src_right = FXSYS_Mul(scale_x, (FX_FLOAT)(clip_rect.right) + base_x); - double src_top = FXSYS_Mul(scale_y, (FX_FLOAT)(clip_rect.top) + base_y); - double src_bottom = FXSYS_Mul(scale_y, (FX_FLOAT)(clip_rect.bottom) + base_y); - if (src_left > src_right) { - double temp = src_left; - src_left = src_right; - src_right = temp; - } - if (src_top > src_bottom) { - double temp = src_top; - src_top = src_bottom; - src_bottom = temp; - } - m_SrcClip.left = (int)FXSYS_floor((FX_FLOAT)src_left); - m_SrcClip.right = (int)FXSYS_ceil((FX_FLOAT)src_right); - m_SrcClip.top = (int)FXSYS_floor((FX_FLOAT)src_top); - m_SrcClip.bottom = (int)FXSYS_ceil((FX_FLOAT)src_bottom); - FX_RECT src_rect(0, 0, m_SrcWidth, m_SrcHeight); - m_SrcClip.Intersect(src_rect); - if (m_SrcBpp == 1) { - if (m_DestBpp == 8) { - m_TransMethod = 1; - } else { - m_TransMethod = 2; + break; + } + case 4: { + for (int col = m_DestClip.left; col < m_DestClip.right; col++) { + PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); + int dest_a = 0, dest_r = 0; + for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; + j++) { + int pixel_weight = + pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; + pixel_weight = pixel_weight * src_scan_mask[j] / 255; + dest_r += pixel_weight * src_scan[j]; + dest_a += pixel_weight; + } + if (m_Flags & FXDIB_BICUBIC_INTERPOL) { + dest_r = dest_r < 0 ? 0 : dest_r > 16711680 ? 16711680 : dest_r; + dest_a = dest_a < 0 ? 0 : dest_a > 65536 ? 65536 : dest_a; + } + *dest_scan++ = (uint8_t)(dest_r >> 16); + *dest_scan_mask++ = (uint8_t)((dest_a * 255) >> 16); } - } else if (m_SrcBpp == 8) { - if (m_DestBpp == 8) { - if (!m_bHasAlpha) { - m_TransMethod = 3; + break; + } + case 5: { + for (int col = m_DestClip.left; col < m_DestClip.right; col++) { + PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); + int dest_r_y = 0, dest_g_m = 0, dest_b_c = 0; + for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; + j++) { + int pixel_weight = + pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; + unsigned long argb_cmyk = m_pSrcPalette[src_scan[j]]; + if (m_DestFormat == FXDIB_Rgb) { + dest_r_y += pixel_weight * (uint8_t)(argb_cmyk >> 16); + dest_g_m += pixel_weight * (uint8_t)(argb_cmyk >> 8); + dest_b_c += pixel_weight * (uint8_t)argb_cmyk; } else { - m_TransMethod = 4; + dest_b_c += pixel_weight * (uint8_t)(argb_cmyk >> 24); + dest_g_m += pixel_weight * (uint8_t)(argb_cmyk >> 16); + dest_r_y += pixel_weight * (uint8_t)(argb_cmyk >> 8); } - } else { - if (!m_bHasAlpha) { - m_TransMethod = 5; + } + if (m_Flags & FXDIB_BICUBIC_INTERPOL) { + dest_r_y = + dest_r_y < 0 ? 0 : dest_r_y > 16711680 ? 16711680 : dest_r_y; + dest_g_m = + dest_g_m < 0 ? 0 : dest_g_m > 16711680 ? 16711680 : dest_g_m; + dest_b_c = + dest_b_c < 0 ? 0 : dest_b_c > 16711680 ? 16711680 : dest_b_c; + } + *dest_scan++ = (uint8_t)(dest_b_c >> 16); + *dest_scan++ = (uint8_t)(dest_g_m >> 16); + *dest_scan++ = (uint8_t)(dest_r_y >> 16); + } + break; + } + case 6: { + for (int col = m_DestClip.left; col < m_DestClip.right; col++) { + PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); + int dest_a = 0, dest_r_y = 0, dest_g_m = 0, dest_b_c = 0; + for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; + j++) { + int pixel_weight = + pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; + pixel_weight = pixel_weight * src_scan_mask[j] / 255; + unsigned long argb_cmyk = m_pSrcPalette[src_scan[j]]; + if (m_DestFormat == FXDIB_Rgba) { + dest_r_y += pixel_weight * (uint8_t)(argb_cmyk >> 16); + dest_g_m += pixel_weight * (uint8_t)(argb_cmyk >> 8); + dest_b_c += pixel_weight * (uint8_t)argb_cmyk; } else { - m_TransMethod = 6; + dest_b_c += pixel_weight * (uint8_t)(argb_cmyk >> 24); + dest_g_m += pixel_weight * (uint8_t)(argb_cmyk >> 16); + dest_r_y += pixel_weight * (uint8_t)(argb_cmyk >> 8); } + dest_a += pixel_weight; + } + if (m_Flags & FXDIB_BICUBIC_INTERPOL) { + dest_b_c = + dest_b_c < 0 ? 0 : dest_b_c > 16711680 ? 16711680 : dest_b_c; + dest_g_m = + dest_g_m < 0 ? 0 : dest_g_m > 16711680 ? 16711680 : dest_g_m; + dest_r_y = + dest_r_y < 0 ? 0 : dest_r_y > 16711680 ? 16711680 : dest_r_y; + dest_a = dest_a < 0 ? 0 : dest_a > 65536 ? 65536 : dest_a; + } + *dest_scan++ = (uint8_t)(dest_b_c >> 16); + *dest_scan++ = (uint8_t)(dest_g_m >> 16); + *dest_scan++ = (uint8_t)(dest_r_y >> 16); + *dest_scan_mask++ = (uint8_t)((dest_a * 255) >> 16); } - } else { - if (!m_bHasAlpha) { - m_TransMethod = 7; - } else { - m_TransMethod = 8; + break; + } + case 7: { + for (int col = m_DestClip.left; col < m_DestClip.right; col++) { + PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); + int dest_r_y = 0, dest_g_m = 0, dest_b_c = 0; + for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; + j++) { + int pixel_weight = + pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; + const uint8_t* src_pixel = src_scan + j * Bpp; + dest_b_c += pixel_weight * (*src_pixel++); + dest_g_m += pixel_weight * (*src_pixel++); + dest_r_y += pixel_weight * (*src_pixel); + } + if (m_Flags & FXDIB_BICUBIC_INTERPOL) { + dest_b_c = + dest_b_c < 0 ? 0 : dest_b_c > 16711680 ? 16711680 : dest_b_c; + dest_g_m = + dest_g_m < 0 ? 0 : dest_g_m > 16711680 ? 16711680 : dest_g_m; + dest_r_y = + dest_r_y < 0 ? 0 : dest_r_y > 16711680 ? 16711680 : dest_r_y; + } + *dest_scan++ = (uint8_t)((dest_b_c) >> 16); + *dest_scan++ = (uint8_t)((dest_g_m) >> 16); + *dest_scan++ = (uint8_t)((dest_r_y) >> 16); + dest_scan += Bpp - 3; } - } -} -FX_BOOL CStretchEngine::Continue(IFX_Pause* pPause) -{ - while (m_State == 1) { - if (ContinueStretchHorz(pPause)) { - return TRUE; - } - m_State = 2; - StretchVert(); - } - return FALSE; -} -CStretchEngine::~CStretchEngine() -{ - if (m_pDestScanline) { - FX_Free(m_pDestScanline); - } - if (m_pInterBuf) { - FX_Free(m_pInterBuf); - } - if (m_pExtraAlphaBuf) { - FX_Free(m_pExtraAlphaBuf); - } - if (m_pDestMaskScanline) { - FX_Free(m_pDestMaskScanline); - } -} -FX_BOOL CStretchEngine::StartStretchHorz() -{ - if (m_DestWidth == 0 || m_pDestScanline == NULL || m_SrcClip.Height() > (int)((1U << 29) / m_InterPitch) || m_SrcClip.Height() == 0) { - return FALSE; - } - m_pInterBuf = FX_TryAlloc(unsigned char, m_SrcClip.Height() * m_InterPitch); - if (m_pInterBuf == NULL) { - return FALSE; - } - if (m_pSource && m_bHasAlpha && m_pSource->m_pAlphaMask) { - m_pExtraAlphaBuf = FX_Alloc2D(unsigned char, m_SrcClip.Height(), m_ExtraMaskPitch); - FX_DWORD size = (m_DestClip.Width() * 8 + 31) / 32 * 4; - m_pDestMaskScanline = FX_TryAlloc(unsigned char, size); - if (!m_pDestMaskScanline) { - return FALSE; + break; + } + case 8: { + for (int col = m_DestClip.left; col < m_DestClip.right; col++) { + PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); + int dest_a = 0, dest_r_y = 0, dest_g_m = 0, dest_b_c = 0; + for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; + j++) { + int pixel_weight = + pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; + const uint8_t* src_pixel = src_scan + j * Bpp; + if (m_DestFormat == FXDIB_Argb) { + pixel_weight = pixel_weight * src_pixel[3] / 255; + } else { + pixel_weight = pixel_weight * src_scan_mask[j] / 255; + } + dest_b_c += pixel_weight * (*src_pixel++); + dest_g_m += pixel_weight * (*src_pixel++); + dest_r_y += pixel_weight * (*src_pixel); + dest_a += pixel_weight; + } + if (m_Flags & FXDIB_BICUBIC_INTERPOL) { + dest_r_y = + dest_r_y < 0 ? 0 : dest_r_y > 16711680 ? 16711680 : dest_r_y; + dest_g_m = + dest_g_m < 0 ? 0 : dest_g_m > 16711680 ? 16711680 : dest_g_m; + dest_b_c = + dest_b_c < 0 ? 0 : dest_b_c > 16711680 ? 16711680 : dest_b_c; + dest_a = dest_a < 0 ? 0 : dest_a > 65536 ? 65536 : dest_a; + } + *dest_scan++ = (uint8_t)((dest_b_c) >> 16); + *dest_scan++ = (uint8_t)((dest_g_m) >> 16); + *dest_scan++ = (uint8_t)((dest_r_y) >> 16); + if (m_DestFormat == FXDIB_Argb) { + *dest_scan = (uint8_t)((dest_a * 255) >> 16); + } + if (dest_scan_mask) { + *dest_scan_mask++ = (uint8_t)((dest_a * 255) >> 16); + } + dest_scan += Bpp - 3; } + break; + } } - m_WeightTable.Calc(m_DestWidth, m_DestClip.left, m_DestClip.right, m_SrcWidth, m_SrcClip.left, m_SrcClip.right, m_Flags); - if (m_WeightTable.m_pWeightTables == NULL) { - return FALSE; - } - m_CurRow = m_SrcClip.top; - m_State = 1; - return TRUE; + rows_to_go--; + } + return FALSE; } -#define FX_STRECH_PAUSE_ROWS 10 -FX_BOOL CStretchEngine::ContinueStretchHorz(IFX_Pause* pPause) -{ - if (!m_DestWidth) { - return 0; - } - if (m_pSource->SkipToScanline(m_CurRow, pPause)) { - return TRUE; - } - int Bpp = m_DestBpp / 8; - int rows_to_go = FX_STRECH_PAUSE_ROWS; - for (; m_CurRow < m_SrcClip.bottom; m_CurRow ++) { - if (rows_to_go == 0) { - if (pPause && pPause->NeedToPauseNow()) { - return TRUE; - } - rows_to_go = FX_STRECH_PAUSE_ROWS; +void CStretchEngine::StretchVert() { + if (m_DestHeight == 0) { + return; + } + CWeightTable table; + table.Calc(m_DestHeight, m_DestClip.top, m_DestClip.bottom, m_SrcHeight, + m_SrcClip.top, m_SrcClip.bottom, m_Flags); + if (table.m_pWeightTables == NULL) { + return; + } + int DestBpp = m_DestBpp / 8; + for (int row = m_DestClip.top; row < m_DestClip.bottom; row++) { + unsigned char* dest_scan = m_pDestScanline; + unsigned char* dest_sacn_mask = m_pDestMaskScanline; + PixelWeight* pPixelWeights = table.GetPixelWeight(row); + switch (m_TransMethod) { + case 1: + case 2: + case 3: { + for (int col = m_DestClip.left; col < m_DestClip.right; col++) { + unsigned char* src_scan = + m_pInterBuf + (col - m_DestClip.left) * DestBpp; + int dest_a = 0; + for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; + j++) { + int pixel_weight = + pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; + dest_a += + pixel_weight * src_scan[(j - m_SrcClip.top) * m_InterPitch]; + } + if (m_Flags & FXDIB_BICUBIC_INTERPOL) { + dest_a = dest_a < 0 ? 0 : dest_a > 16711680 ? 16711680 : dest_a; + } + *dest_scan = (uint8_t)(dest_a >> 16); + dest_scan += DestBpp; } - const uint8_t* src_scan = m_pSource->GetScanline(m_CurRow); - uint8_t* dest_scan = m_pInterBuf + (m_CurRow - m_SrcClip.top) * m_InterPitch; - const uint8_t* src_scan_mask = NULL; - uint8_t* dest_scan_mask = NULL; - if (m_pExtraAlphaBuf) { - src_scan_mask = m_pSource->m_pAlphaMask->GetScanline(m_CurRow); - dest_scan_mask = m_pExtraAlphaBuf + (m_CurRow - m_SrcClip.top) * m_ExtraMaskPitch; + break; + } + case 4: { + for (int col = m_DestClip.left; col < m_DestClip.right; col++) { + unsigned char* src_scan = + m_pInterBuf + (col - m_DestClip.left) * DestBpp; + unsigned char* src_scan_mask = + m_pExtraAlphaBuf + (col - m_DestClip.left); + int dest_a = 0, dest_k = 0; + for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; + j++) { + int pixel_weight = + pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; + dest_k += + pixel_weight * src_scan[(j - m_SrcClip.top) * m_InterPitch]; + dest_a += pixel_weight * + src_scan_mask[(j - m_SrcClip.top) * m_ExtraMaskPitch]; + } + if (m_Flags & FXDIB_BICUBIC_INTERPOL) { + dest_k = dest_k < 0 ? 0 : dest_k > 16711680 ? 16711680 : dest_k; + dest_a = dest_a < 0 ? 0 : dest_a > 16711680 ? 16711680 : dest_a; + } + *dest_scan = (uint8_t)(dest_k >> 16); + dest_scan += DestBpp; + *dest_sacn_mask++ = (uint8_t)(dest_a >> 16); } - switch (m_TransMethod) { - case 1: - case 2: { - for (int col = m_DestClip.left; col < m_DestClip.right; col ++) { - PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); - int dest_a = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) { - int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - if (src_scan[j / 8] & (1 << (7 - j % 8))) { - dest_a += pixel_weight * 255; - } - } - if (m_Flags & FXDIB_BICUBIC_INTERPOL) { - dest_a = dest_a < 0 ? 0 : dest_a > 16711680 ? 16711680 : dest_a; - } - *dest_scan++ = (uint8_t)(dest_a >> 16); - } - break; - } - case 3: { - for (int col = m_DestClip.left; col < m_DestClip.right; col ++) { - PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); - int dest_a = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) { - int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - dest_a += pixel_weight * src_scan[j]; - } - if (m_Flags & FXDIB_BICUBIC_INTERPOL) { - dest_a = dest_a < 0 ? 0 : dest_a > 16711680 ? 16711680 : dest_a; - } - *dest_scan++ = (uint8_t)(dest_a >> 16); - } - break; - } - case 4: { - for (int col = m_DestClip.left; col < m_DestClip.right; col ++) { - PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); - int dest_a = 0, dest_r = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) { - int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - pixel_weight = pixel_weight * src_scan_mask[j] / 255; - dest_r += pixel_weight * src_scan[j]; - dest_a += pixel_weight; - } - if (m_Flags & FXDIB_BICUBIC_INTERPOL) { - dest_r = dest_r < 0 ? 0 : dest_r > 16711680 ? 16711680 : dest_r; - dest_a = dest_a < 0 ? 0 : dest_a > 65536 ? 65536 : dest_a; - } - *dest_scan++ = (uint8_t)(dest_r >> 16); - *dest_scan_mask++ = (uint8_t)((dest_a * 255) >> 16); - } - break; - } - case 5: { - for (int col = m_DestClip.left; col < m_DestClip.right; col ++) { - PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); - int dest_r_y = 0, dest_g_m = 0, dest_b_c = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) { - int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - unsigned long argb_cmyk = m_pSrcPalette[src_scan[j]]; - if (m_DestFormat == FXDIB_Rgb) { - dest_r_y += pixel_weight * (uint8_t)(argb_cmyk >> 16); - dest_g_m += pixel_weight * (uint8_t)(argb_cmyk >> 8); - dest_b_c += pixel_weight * (uint8_t)argb_cmyk; - } else { - dest_b_c += pixel_weight * (uint8_t)(argb_cmyk >> 24); - dest_g_m += pixel_weight * (uint8_t)(argb_cmyk >> 16); - dest_r_y += pixel_weight * (uint8_t)(argb_cmyk >> 8); - } - } - if (m_Flags & FXDIB_BICUBIC_INTERPOL) { - dest_r_y = dest_r_y < 0 ? 0 : dest_r_y > 16711680 ? 16711680 : dest_r_y; - dest_g_m = dest_g_m < 0 ? 0 : dest_g_m > 16711680 ? 16711680 : dest_g_m; - dest_b_c = dest_b_c < 0 ? 0 : dest_b_c > 16711680 ? 16711680 : dest_b_c; - } - *dest_scan++ = (uint8_t)(dest_b_c >> 16); - *dest_scan++ = (uint8_t)(dest_g_m >> 16); - *dest_scan++ = (uint8_t)(dest_r_y >> 16); - } - break; - } - case 6: { - for (int col = m_DestClip.left; col < m_DestClip.right; col ++) { - PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); - int dest_a = 0, dest_r_y = 0, dest_g_m = 0, dest_b_c = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) { - int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - pixel_weight = pixel_weight * src_scan_mask[j] / 255; - unsigned long argb_cmyk = m_pSrcPalette[src_scan[j]]; - if (m_DestFormat == FXDIB_Rgba) { - dest_r_y += pixel_weight * (uint8_t)(argb_cmyk >> 16); - dest_g_m += pixel_weight * (uint8_t)(argb_cmyk >> 8); - dest_b_c += pixel_weight * (uint8_t)argb_cmyk; - } else { - dest_b_c += pixel_weight * (uint8_t)(argb_cmyk >> 24); - dest_g_m += pixel_weight * (uint8_t)(argb_cmyk >> 16); - dest_r_y += pixel_weight * (uint8_t)(argb_cmyk >> 8); - } - dest_a += pixel_weight; - } - if (m_Flags & FXDIB_BICUBIC_INTERPOL) { - dest_b_c = dest_b_c < 0 ? 0 : dest_b_c > 16711680 ? 16711680 : dest_b_c; - dest_g_m = dest_g_m < 0 ? 0 : dest_g_m > 16711680 ? 16711680 : dest_g_m; - dest_r_y = dest_r_y < 0 ? 0 : dest_r_y > 16711680 ? 16711680 : dest_r_y; - dest_a = dest_a < 0 ? 0 : dest_a > 65536 ? 65536 : dest_a; - } - *dest_scan++ = (uint8_t)(dest_b_c >> 16); - *dest_scan++ = (uint8_t)(dest_g_m >> 16); - *dest_scan++ = (uint8_t)(dest_r_y >> 16); - *dest_scan_mask++ = (uint8_t)((dest_a * 255) >> 16); - } - break; - } - case 7: { - for (int col = m_DestClip.left; col < m_DestClip.right; col ++) { - PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); - int dest_r_y = 0, dest_g_m = 0, dest_b_c = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) { - int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - const uint8_t* src_pixel = src_scan + j * Bpp; - dest_b_c += pixel_weight * (*src_pixel++); - dest_g_m += pixel_weight * (*src_pixel++); - dest_r_y += pixel_weight * (*src_pixel); - } - if (m_Flags & FXDIB_BICUBIC_INTERPOL) { - dest_b_c = dest_b_c < 0 ? 0 : dest_b_c > 16711680 ? 16711680 : dest_b_c; - dest_g_m = dest_g_m < 0 ? 0 : dest_g_m > 16711680 ? 16711680 : dest_g_m; - dest_r_y = dest_r_y < 0 ? 0 : dest_r_y > 16711680 ? 16711680 : dest_r_y; - } - *dest_scan++ = (uint8_t)((dest_b_c) >> 16); - *dest_scan++ = (uint8_t)((dest_g_m) >> 16); - *dest_scan++ = (uint8_t)((dest_r_y) >> 16); - dest_scan += Bpp - 3; - } - break; - } - case 8: { - for (int col = m_DestClip.left; col < m_DestClip.right; col ++) { - PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); - int dest_a = 0, dest_r_y = 0, dest_g_m = 0, dest_b_c = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) { - int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - const uint8_t* src_pixel = src_scan + j * Bpp; - if (m_DestFormat == FXDIB_Argb) { - pixel_weight = pixel_weight * src_pixel[3] / 255; - } else { - pixel_weight = pixel_weight * src_scan_mask[j] / 255; - } - dest_b_c += pixel_weight * (*src_pixel++); - dest_g_m += pixel_weight * (*src_pixel++); - dest_r_y += pixel_weight * (*src_pixel); - dest_a += pixel_weight; - } - if (m_Flags & FXDIB_BICUBIC_INTERPOL) { - dest_r_y = dest_r_y < 0 ? 0 : dest_r_y > 16711680 ? 16711680 : dest_r_y; - dest_g_m = dest_g_m < 0 ? 0 : dest_g_m > 16711680 ? 16711680 : dest_g_m; - dest_b_c = dest_b_c < 0 ? 0 : dest_b_c > 16711680 ? 16711680 : dest_b_c; - dest_a = dest_a < 0 ? 0 : dest_a > 65536 ? 65536 : dest_a; - } - *dest_scan++ = (uint8_t)((dest_b_c) >> 16); - *dest_scan++ = (uint8_t)((dest_g_m) >> 16); - *dest_scan++ = (uint8_t)((dest_r_y) >> 16); - if (m_DestFormat == FXDIB_Argb) { - *dest_scan = (uint8_t)((dest_a * 255) >> 16); - } - if (dest_scan_mask) { - *dest_scan_mask++ = (uint8_t)((dest_a * 255) >> 16); - } - dest_scan += Bpp - 3; - } - break; - } + break; + } + case 5: + case 7: { + for (int col = m_DestClip.left; col < m_DestClip.right; col++) { + unsigned char* src_scan = + m_pInterBuf + (col - m_DestClip.left) * DestBpp; + int dest_r_y = 0, dest_g_m = 0, dest_b_c = 0; + for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; + j++) { + int pixel_weight = + pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; + const uint8_t* src_pixel = + src_scan + (j - m_SrcClip.top) * m_InterPitch; + dest_b_c += pixel_weight * (*src_pixel++); + dest_g_m += pixel_weight * (*src_pixel++); + dest_r_y += pixel_weight * (*src_pixel); + } + if (m_Flags & FXDIB_BICUBIC_INTERPOL) { + dest_r_y = + dest_r_y < 0 ? 0 : dest_r_y > 16711680 ? 16711680 : dest_r_y; + dest_g_m = + dest_g_m < 0 ? 0 : dest_g_m > 16711680 ? 16711680 : dest_g_m; + dest_b_c = + dest_b_c < 0 ? 0 : dest_b_c > 16711680 ? 16711680 : dest_b_c; + } + dest_scan[0] = (uint8_t)((dest_b_c) >> 16); + dest_scan[1] = (uint8_t)((dest_g_m) >> 16); + dest_scan[2] = (uint8_t)((dest_r_y) >> 16); + dest_scan += DestBpp; } - rows_to_go --; - } - return FALSE; -} -void CStretchEngine::StretchVert() -{ - if (m_DestHeight == 0) { - return; - } - CWeightTable table; - table.Calc(m_DestHeight, m_DestClip.top, m_DestClip.bottom, m_SrcHeight, m_SrcClip.top, m_SrcClip.bottom, m_Flags); - if (table.m_pWeightTables == NULL) { - return; - } - int DestBpp = m_DestBpp / 8; - for (int row = m_DestClip.top; row < m_DestClip.bottom; row ++) { - unsigned char* dest_scan = m_pDestScanline; - unsigned char* dest_sacn_mask = m_pDestMaskScanline; - PixelWeight* pPixelWeights = table.GetPixelWeight(row); - switch(m_TransMethod) { - case 1: - case 2: - case 3: { - for (int col = m_DestClip.left; col < m_DestClip.right; col ++) { - unsigned char* src_scan = m_pInterBuf + (col - m_DestClip.left) * DestBpp; - int dest_a = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) { - int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - dest_a += pixel_weight * src_scan[(j - m_SrcClip.top) * m_InterPitch]; - } - if (m_Flags & FXDIB_BICUBIC_INTERPOL) { - dest_a = dest_a < 0 ? 0 : dest_a > 16711680 ? 16711680 : dest_a; - } - *dest_scan = (uint8_t)(dest_a >> 16); - dest_scan += DestBpp; - } - break; - } - case 4: { - for (int col = m_DestClip.left; col < m_DestClip.right; col ++) { - unsigned char* src_scan = m_pInterBuf + (col - m_DestClip.left) * DestBpp; - unsigned char* src_scan_mask = m_pExtraAlphaBuf + (col - m_DestClip.left); - int dest_a = 0, dest_k = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) { - int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - dest_k += pixel_weight * src_scan[(j - m_SrcClip.top) * m_InterPitch]; - dest_a += pixel_weight * src_scan_mask[(j - m_SrcClip.top) * m_ExtraMaskPitch]; - } - if (m_Flags & FXDIB_BICUBIC_INTERPOL) { - dest_k = dest_k < 0 ? 0 : dest_k > 16711680 ? 16711680 : dest_k; - dest_a = dest_a < 0 ? 0 : dest_a > 16711680 ? 16711680 : dest_a; - } - *dest_scan = (uint8_t)(dest_k >> 16); - dest_scan += DestBpp; - *dest_sacn_mask++ = (uint8_t)(dest_a >> 16); - } - break; - } - case 5: - case 7: { - for (int col = m_DestClip.left; col < m_DestClip.right; col ++) { - unsigned char* src_scan = m_pInterBuf + (col - m_DestClip.left) * DestBpp; - int dest_r_y = 0, dest_g_m = 0, dest_b_c = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) { - int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - const uint8_t* src_pixel = src_scan + (j - m_SrcClip.top) * m_InterPitch; - dest_b_c += pixel_weight * (*src_pixel++); - dest_g_m += pixel_weight * (*src_pixel++); - dest_r_y += pixel_weight * (*src_pixel); - } - if (m_Flags & FXDIB_BICUBIC_INTERPOL) { - dest_r_y = dest_r_y < 0 ? 0 : dest_r_y > 16711680 ? 16711680 : dest_r_y; - dest_g_m = dest_g_m < 0 ? 0 : dest_g_m > 16711680 ? 16711680 : dest_g_m; - dest_b_c = dest_b_c < 0 ? 0 : dest_b_c > 16711680 ? 16711680 : dest_b_c; - } - dest_scan[0] = (uint8_t)((dest_b_c) >> 16); - dest_scan[1] = (uint8_t)((dest_g_m) >> 16); - dest_scan[2] = (uint8_t)((dest_r_y) >> 16); - dest_scan += DestBpp; - } - break; - } - case 6: - case 8: { - for (int col = m_DestClip.left; col < m_DestClip.right; col ++) { - unsigned char* src_scan = m_pInterBuf + (col - m_DestClip.left) * DestBpp; - unsigned char* src_scan_mask = NULL; - if (m_DestFormat != FXDIB_Argb) { - src_scan_mask = m_pExtraAlphaBuf + (col - m_DestClip.left); - } - int dest_a = 0, dest_r_y = 0, dest_g_m = 0, dest_b_c = 0; - for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) { - int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; - const uint8_t* src_pixel = src_scan + (j - m_SrcClip.top) * m_InterPitch; - int mask_v = 255; - if (src_scan_mask) { - mask_v = src_scan_mask[(j - m_SrcClip.top) * m_ExtraMaskPitch]; - } - dest_b_c += pixel_weight * (*src_pixel++); - dest_g_m += pixel_weight * (*src_pixel++); - dest_r_y += pixel_weight * (*src_pixel); - if (m_DestFormat == FXDIB_Argb) { - dest_a += pixel_weight * (*(src_pixel + 1)); - } else { - dest_a += pixel_weight * mask_v; - } - } - if (m_Flags & FXDIB_BICUBIC_INTERPOL) { - dest_r_y = dest_r_y < 0 ? 0 : dest_r_y > 16711680 ? 16711680 : dest_r_y; - dest_g_m = dest_g_m < 0 ? 0 : dest_g_m > 16711680 ? 16711680 : dest_g_m; - dest_b_c = dest_b_c < 0 ? 0 : dest_b_c > 16711680 ? 16711680 : dest_b_c; - dest_a = dest_a < 0 ? 0 : dest_a > 16711680 ? 16711680 : dest_a; - } - if (dest_a) { - int r = ((FX_DWORD)dest_r_y) * 255 / dest_a; - int g = ((FX_DWORD)dest_g_m) * 255 / dest_a; - int b = ((FX_DWORD)dest_b_c) * 255 / dest_a; - dest_scan[0] = b > 255 ? 255 : b < 0 ? 0 : b; - dest_scan[1] = g > 255 ? 255 : g < 0 ? 0 : g; - dest_scan[2] = r > 255 ? 255 : r < 0 ? 0 : r; - } - if (m_DestFormat == FXDIB_Argb) { - dest_scan[3] = (uint8_t)((dest_a) >> 16); - } else { - *dest_sacn_mask = (uint8_t)((dest_a) >> 16); - } - dest_scan += DestBpp; - if (dest_sacn_mask) { - dest_sacn_mask++; - } - } - break; - } + break; + } + case 6: + case 8: { + for (int col = m_DestClip.left; col < m_DestClip.right; col++) { + unsigned char* src_scan = + m_pInterBuf + (col - m_DestClip.left) * DestBpp; + unsigned char* src_scan_mask = NULL; + if (m_DestFormat != FXDIB_Argb) { + src_scan_mask = m_pExtraAlphaBuf + (col - m_DestClip.left); + } + int dest_a = 0, dest_r_y = 0, dest_g_m = 0, dest_b_c = 0; + for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; + j++) { + int pixel_weight = + pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; + const uint8_t* src_pixel = + src_scan + (j - m_SrcClip.top) * m_InterPitch; + int mask_v = 255; + if (src_scan_mask) { + mask_v = src_scan_mask[(j - m_SrcClip.top) * m_ExtraMaskPitch]; + } + dest_b_c += pixel_weight * (*src_pixel++); + dest_g_m += pixel_weight * (*src_pixel++); + dest_r_y += pixel_weight * (*src_pixel); + if (m_DestFormat == FXDIB_Argb) { + dest_a += pixel_weight * (*(src_pixel + 1)); + } else { + dest_a += pixel_weight * mask_v; + } + } + if (m_Flags & FXDIB_BICUBIC_INTERPOL) { + dest_r_y = + dest_r_y < 0 ? 0 : dest_r_y > 16711680 ? 16711680 : dest_r_y; + dest_g_m = + dest_g_m < 0 ? 0 : dest_g_m > 16711680 ? 16711680 : dest_g_m; + dest_b_c = + dest_b_c < 0 ? 0 : dest_b_c > 16711680 ? 16711680 : dest_b_c; + dest_a = dest_a < 0 ? 0 : dest_a > 16711680 ? 16711680 : dest_a; + } + if (dest_a) { + int r = ((FX_DWORD)dest_r_y) * 255 / dest_a; + int g = ((FX_DWORD)dest_g_m) * 255 / dest_a; + int b = ((FX_DWORD)dest_b_c) * 255 / dest_a; + dest_scan[0] = b > 255 ? 255 : b < 0 ? 0 : b; + dest_scan[1] = g > 255 ? 255 : g < 0 ? 0 : g; + dest_scan[2] = r > 255 ? 255 : r < 0 ? 0 : r; + } + if (m_DestFormat == FXDIB_Argb) { + dest_scan[3] = (uint8_t)((dest_a) >> 16); + } else { + *dest_sacn_mask = (uint8_t)((dest_a) >> 16); + } + dest_scan += DestBpp; + if (dest_sacn_mask) { + dest_sacn_mask++; + } } - m_pDestBitmap->ComposeScanline(row - m_DestClip.top, m_pDestScanline, m_pDestMaskScanline); + break; + } } + m_pDestBitmap->ComposeScanline(row - m_DestClip.top, m_pDestScanline, + m_pDestMaskScanline); + } } -CFX_ImageStretcher::CFX_ImageStretcher() -{ - m_pScanline = NULL; - m_pStretchEngine = NULL; - m_pMaskScanline = NULL; +CFX_ImageStretcher::CFX_ImageStretcher() { + m_pScanline = NULL; + m_pStretchEngine = NULL; + m_pMaskScanline = NULL; } -CFX_ImageStretcher::~CFX_ImageStretcher() -{ - if (m_pScanline) { - FX_Free(m_pScanline); - } - delete m_pStretchEngine; - if (m_pMaskScanline) { - FX_Free(m_pMaskScanline); - } +CFX_ImageStretcher::~CFX_ImageStretcher() { + if (m_pScanline) { + FX_Free(m_pScanline); + } + delete m_pStretchEngine; + if (m_pMaskScanline) { + FX_Free(m_pMaskScanline); + } } -FXDIB_Format _GetStretchedFormat(const CFX_DIBSource* pSrc) -{ - FXDIB_Format format = pSrc->GetFormat(); - if (format == FXDIB_1bppMask) { - format = FXDIB_8bppMask; - } else if (format == FXDIB_1bppRgb) { - format = FXDIB_8bppRgb; - } else if (format == FXDIB_8bppRgb) { - if (pSrc->GetPalette()) { - format = FXDIB_Rgb; - } - } - return format; +FXDIB_Format _GetStretchedFormat(const CFX_DIBSource* pSrc) { + FXDIB_Format format = pSrc->GetFormat(); + if (format == FXDIB_1bppMask) { + format = FXDIB_8bppMask; + } else if (format == FXDIB_1bppRgb) { + format = FXDIB_8bppRgb; + } else if (format == FXDIB_8bppRgb) { + if (pSrc->GetPalette()) { + format = FXDIB_Rgb; + } + } + return format; } FX_BOOL CFX_ImageStretcher::Start(IFX_ScanlineComposer* pDest, - const CFX_DIBSource* pSource, int dest_width, int dest_height, - const FX_RECT& rect, FX_DWORD flags) -{ - m_DestFormat = _GetStretchedFormat(pSource); - m_DestBPP = m_DestFormat & 0xff; - m_pDest = pDest; - m_pSource = pSource; - m_DestWidth = dest_width; - m_DestHeight = dest_height; - m_ClipRect = rect; - m_Flags = flags; - if (pSource->GetFormat() == FXDIB_1bppRgb && pSource->GetPalette()) { - FX_ARGB pal[256]; - int a0, r0, g0, b0, a1, r1, g1, b1; - ArgbDecode(pSource->GetPaletteEntry(0), a0, r0, g0, b0); - ArgbDecode(pSource->GetPaletteEntry(1), a1, r1, g1, b1); - for (int i = 0; i < 256; i ++) { - int a = a0 + (a1 - a0) * i / 255; - int r = r0 + (r1 - r0) * i / 255; - int g = g0 + (g1 - g0) * i / 255; - int b = b0 + (b1 - b0) * i / 255; - pal[i] = ArgbEncode(a, r, g, b); - } - if (!pDest->SetInfo(rect.Width(), rect.Height(), m_DestFormat, pal)) { - return FALSE; - } - } else if (pSource->GetFormat() == FXDIB_1bppCmyk && pSource->GetPalette()) { - FX_CMYK pal[256]; - int c0, m0, y0, k0, c1, m1, y1, k1; - CmykDecode(pSource->GetPaletteEntry(0), c0, m0, y0, k0); - CmykDecode(pSource->GetPaletteEntry(1), c1, m1, y1, k1); - for (int i = 0; i < 256; i ++) { - int c = c0 + (c1 - c0) * i / 255; - int m = m0 + (m1 - m0) * i / 255; - int y = y0 + (y1 - y0) * i / 255; - int k = k0 + (k1 - k0) * i / 255; - pal[i] = CmykEncode(c, m, y, k); - } - if (!pDest->SetInfo(rect.Width(), rect.Height(), m_DestFormat, pal)) { - return FALSE; - } - } else if (!pDest->SetInfo(rect.Width(), rect.Height(), m_DestFormat, NULL)) { - return FALSE; - } - if (flags & FXDIB_DOWNSAMPLE) { - return StartQuickStretch(); - } - return StartStretch(); + const CFX_DIBSource* pSource, + int dest_width, + int dest_height, + const FX_RECT& rect, + FX_DWORD flags) { + m_DestFormat = _GetStretchedFormat(pSource); + m_DestBPP = m_DestFormat & 0xff; + m_pDest = pDest; + m_pSource = pSource; + m_DestWidth = dest_width; + m_DestHeight = dest_height; + m_ClipRect = rect; + m_Flags = flags; + if (pSource->GetFormat() == FXDIB_1bppRgb && pSource->GetPalette()) { + FX_ARGB pal[256]; + int a0, r0, g0, b0, a1, r1, g1, b1; + ArgbDecode(pSource->GetPaletteEntry(0), a0, r0, g0, b0); + ArgbDecode(pSource->GetPaletteEntry(1), a1, r1, g1, b1); + for (int i = 0; i < 256; i++) { + int a = a0 + (a1 - a0) * i / 255; + int r = r0 + (r1 - r0) * i / 255; + int g = g0 + (g1 - g0) * i / 255; + int b = b0 + (b1 - b0) * i / 255; + pal[i] = ArgbEncode(a, r, g, b); + } + if (!pDest->SetInfo(rect.Width(), rect.Height(), m_DestFormat, pal)) { + return FALSE; + } + } else if (pSource->GetFormat() == FXDIB_1bppCmyk && pSource->GetPalette()) { + FX_CMYK pal[256]; + int c0, m0, y0, k0, c1, m1, y1, k1; + CmykDecode(pSource->GetPaletteEntry(0), c0, m0, y0, k0); + CmykDecode(pSource->GetPaletteEntry(1), c1, m1, y1, k1); + for (int i = 0; i < 256; i++) { + int c = c0 + (c1 - c0) * i / 255; + int m = m0 + (m1 - m0) * i / 255; + int y = y0 + (y1 - y0) * i / 255; + int k = k0 + (k1 - k0) * i / 255; + pal[i] = CmykEncode(c, m, y, k); + } + if (!pDest->SetInfo(rect.Width(), rect.Height(), m_DestFormat, pal)) { + return FALSE; + } + } else if (!pDest->SetInfo(rect.Width(), rect.Height(), m_DestFormat, NULL)) { + return FALSE; + } + if (flags & FXDIB_DOWNSAMPLE) { + return StartQuickStretch(); + } + return StartStretch(); } -FX_BOOL CFX_ImageStretcher::Continue(IFX_Pause* pPause) -{ - if (m_Flags & FXDIB_DOWNSAMPLE) { - return ContinueQuickStretch(pPause); - } - return ContinueStretch(pPause); +FX_BOOL CFX_ImageStretcher::Continue(IFX_Pause* pPause) { + if (m_Flags & FXDIB_DOWNSAMPLE) { + return ContinueQuickStretch(pPause); + } + return ContinueStretch(pPause); } -#define MAX_PROGRESSIVE_STRETCH_PIXELS 1000000 -FX_BOOL CFX_ImageStretcher::StartStretch() -{ - m_pStretchEngine = new CStretchEngine(m_pDest, m_DestFormat, m_DestWidth, m_DestHeight, m_ClipRect, m_pSource, m_Flags); - m_pStretchEngine->StartStretchHorz(); - if (m_pSource->GetWidth() * m_pSource->GetHeight() < MAX_PROGRESSIVE_STRETCH_PIXELS) { - m_pStretchEngine->Continue(NULL); - return FALSE; - } - return TRUE; +#define MAX_PROGRESSIVE_STRETCH_PIXELS 1000000 +FX_BOOL CFX_ImageStretcher::StartStretch() { + m_pStretchEngine = + new CStretchEngine(m_pDest, m_DestFormat, m_DestWidth, m_DestHeight, + m_ClipRect, m_pSource, m_Flags); + m_pStretchEngine->StartStretchHorz(); + if (m_pSource->GetWidth() * m_pSource->GetHeight() < + MAX_PROGRESSIVE_STRETCH_PIXELS) { + m_pStretchEngine->Continue(NULL); + return FALSE; + } + return TRUE; } -FX_BOOL CFX_ImageStretcher::ContinueStretch(IFX_Pause* pPause) -{ - if (m_pStretchEngine == NULL) { - return FALSE; - } - return m_pStretchEngine->Continue(pPause); +FX_BOOL CFX_ImageStretcher::ContinueStretch(IFX_Pause* pPause) { + if (m_pStretchEngine == NULL) { + return FALSE; + } + return m_pStretchEngine->Continue(pPause); } -FX_BOOL CFX_ImageStretcher::StartQuickStretch() -{ - m_bFlipX = FALSE; - m_bFlipY = FALSE; - if (m_DestWidth < 0) { - m_bFlipX = TRUE; - m_DestWidth = -m_DestWidth; - } - if (m_DestHeight < 0) { - m_bFlipY = TRUE; - m_DestHeight = -m_DestHeight; - } - m_LineIndex = 0; - FX_DWORD size = m_ClipRect.Width(); - if (size && m_DestBPP > (int)(INT_MAX / size)) { - return FALSE; +FX_BOOL CFX_ImageStretcher::StartQuickStretch() { + m_bFlipX = FALSE; + m_bFlipY = FALSE; + if (m_DestWidth < 0) { + m_bFlipX = TRUE; + m_DestWidth = -m_DestWidth; + } + if (m_DestHeight < 0) { + m_bFlipY = TRUE; + m_DestHeight = -m_DestHeight; + } + m_LineIndex = 0; + FX_DWORD size = m_ClipRect.Width(); + if (size && m_DestBPP > (int)(INT_MAX / size)) { + return FALSE; + } + size *= m_DestBPP; + m_pScanline = FX_Alloc(uint8_t, (size / 8 + 3) / 4 * 4); + if (m_pSource->m_pAlphaMask) { + m_pMaskScanline = FX_Alloc(uint8_t, (m_ClipRect.Width() + 3) / 4 * 4); + } + if (m_pSource->GetWidth() * m_pSource->GetHeight() < + MAX_PROGRESSIVE_STRETCH_PIXELS) { + ContinueQuickStretch(NULL); + return FALSE; + } + return TRUE; +} +FX_BOOL CFX_ImageStretcher::ContinueQuickStretch(IFX_Pause* pPause) { + if (m_pScanline == NULL) { + return FALSE; + } + int result_width = m_ClipRect.Width(), result_height = m_ClipRect.Height(); + int src_height = m_pSource->GetHeight(); + for (; m_LineIndex < result_height; m_LineIndex++) { + int dest_y, src_y; + if (m_bFlipY) { + dest_y = result_height - m_LineIndex - 1; + src_y = (m_DestHeight - (dest_y + m_ClipRect.top) - 1) * src_height / + m_DestHeight; + } else { + dest_y = m_LineIndex; + src_y = (dest_y + m_ClipRect.top) * src_height / m_DestHeight; } - size *= m_DestBPP; - m_pScanline = FX_Alloc(uint8_t, (size / 8 + 3) / 4 * 4); - if (m_pSource->m_pAlphaMask) { - m_pMaskScanline = FX_Alloc(uint8_t, (m_ClipRect.Width() + 3) / 4 * 4); + if (src_y >= src_height) { + src_y = src_height - 1; } - if (m_pSource->GetWidth() * m_pSource->GetHeight() < MAX_PROGRESSIVE_STRETCH_PIXELS) { - ContinueQuickStretch(NULL); - return FALSE; + if (src_y < 0) { + src_y = 0; } - return TRUE; -} -FX_BOOL CFX_ImageStretcher::ContinueQuickStretch(IFX_Pause* pPause) -{ - if (m_pScanline == NULL) { - return FALSE; + if (m_pSource->SkipToScanline(src_y, pPause)) { + return TRUE; } - int result_width = m_ClipRect.Width(), result_height = m_ClipRect.Height(); - int src_height = m_pSource->GetHeight(); - for (; m_LineIndex < result_height; m_LineIndex ++) { - int dest_y, src_y; - if (m_bFlipY) { - dest_y = result_height - m_LineIndex - 1; - src_y = (m_DestHeight - (dest_y + m_ClipRect.top) - 1) * src_height / m_DestHeight; - } else { - dest_y = m_LineIndex; - src_y = (dest_y + m_ClipRect.top) * src_height / m_DestHeight; - } - if (src_y >= src_height) { - src_y = src_height - 1; - } - if (src_y < 0) { - src_y = 0; - } - if (m_pSource->SkipToScanline(src_y, pPause)) { - return TRUE; - } - m_pSource->DownSampleScanline(src_y, m_pScanline, m_DestBPP, m_DestWidth, m_bFlipX, m_ClipRect.left, result_width); - if (m_pMaskScanline) { - m_pSource->m_pAlphaMask->DownSampleScanline(src_y, m_pMaskScanline, 1, m_DestWidth, m_bFlipX, m_ClipRect.left, result_width); - } - m_pDest->ComposeScanline(dest_y, m_pScanline, m_pMaskScanline); + m_pSource->DownSampleScanline(src_y, m_pScanline, m_DestBPP, m_DestWidth, + m_bFlipX, m_ClipRect.left, result_width); + if (m_pMaskScanline) { + m_pSource->m_pAlphaMask->DownSampleScanline( + src_y, m_pMaskScanline, 1, m_DestWidth, m_bFlipX, m_ClipRect.left, + result_width); } - return FALSE; + m_pDest->ComposeScanline(dest_y, m_pScanline, m_pMaskScanline); + } + return FALSE; } diff --git a/core/src/fxge/dib/fx_dib_main.cpp b/core/src/fxge/dib/fx_dib_main.cpp index 8a864f10a1..3c886e5cfe 100644 --- a/core/src/fxge/dib/fx_dib_main.cpp +++ b/core/src/fxge/dib/fx_dib_main.cpp @@ -9,1660 +9,1727 @@ #include "../../../include/fxcodec/fx_codec.h" #include "dib_int.h" #include -FX_BOOL ConvertBuffer(FXDIB_Format dest_format, uint8_t* dest_buf, int dest_pitch, int width, int height, - const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, FX_DWORD*& pal, void* pIccTransform); -void CmykDecode(FX_DWORD cmyk, int& c, int& m, int& y, int& k) -{ - c = FXSYS_GetCValue(cmyk); - m = FXSYS_GetMValue(cmyk); - y = FXSYS_GetYValue(cmyk); - k = FXSYS_GetKValue(cmyk); +FX_BOOL ConvertBuffer(FXDIB_Format dest_format, + uint8_t* dest_buf, + int dest_pitch, + int width, + int height, + const CFX_DIBSource* pSrcBitmap, + int src_left, + int src_top, + FX_DWORD*& pal, + void* pIccTransform); +void CmykDecode(FX_DWORD cmyk, int& c, int& m, int& y, int& k) { + c = FXSYS_GetCValue(cmyk); + m = FXSYS_GetMValue(cmyk); + y = FXSYS_GetYValue(cmyk); + k = FXSYS_GetKValue(cmyk); } -void ArgbDecode(FX_DWORD argb, int& a, int& r, int& g, int& b) -{ - a = FXARGB_A(argb); - r = FXARGB_R(argb); - g = FXARGB_G(argb); - b = FXARGB_B(argb); +void ArgbDecode(FX_DWORD argb, int& a, int& r, int& g, int& b) { + a = FXARGB_A(argb); + r = FXARGB_R(argb); + g = FXARGB_G(argb); + b = FXARGB_B(argb); } -void ArgbDecode(FX_DWORD argb, int& a, FX_COLORREF& rgb) -{ - a = FXARGB_A(argb); - rgb = FXSYS_RGB(FXARGB_R(argb), FXARGB_G(argb), FXARGB_B(argb)); +void ArgbDecode(FX_DWORD argb, int& a, FX_COLORREF& rgb) { + a = FXARGB_A(argb); + rgb = FXSYS_RGB(FXARGB_R(argb), FXARGB_G(argb), FXARGB_B(argb)); } -FX_DWORD ArgbEncode(int a, FX_COLORREF rgb) -{ - return FXARGB_MAKE(a, FXSYS_GetRValue(rgb), FXSYS_GetGValue(rgb), FXSYS_GetBValue(rgb)); +FX_DWORD ArgbEncode(int a, FX_COLORREF rgb) { + return FXARGB_MAKE(a, FXSYS_GetRValue(rgb), FXSYS_GetGValue(rgb), + FXSYS_GetBValue(rgb)); } -CFX_DIBSource::CFX_DIBSource() -{ - m_bpp = 0; - m_AlphaFlag = 0; - m_Width = m_Height = 0; - m_Pitch = 0; - m_pPalette = NULL; - m_pAlphaMask = NULL; +CFX_DIBSource::CFX_DIBSource() { + m_bpp = 0; + m_AlphaFlag = 0; + m_Width = m_Height = 0; + m_Pitch = 0; + m_pPalette = NULL; + m_pAlphaMask = NULL; } -CFX_DIBSource::~CFX_DIBSource() -{ - if (m_pPalette) { - FX_Free(m_pPalette); - } - delete m_pAlphaMask; +CFX_DIBSource::~CFX_DIBSource() { + if (m_pPalette) { + FX_Free(m_pPalette); + } + delete m_pAlphaMask; } -CFX_DIBitmap::CFX_DIBitmap() -{ - m_bExtBuf = FALSE; - m_pBuffer = NULL; - m_pPalette = NULL; +CFX_DIBitmap::CFX_DIBitmap() { + m_bExtBuf = FALSE; + m_pBuffer = NULL; + m_pPalette = NULL; } -#define _MAX_OOM_LIMIT_ 12000000 -FX_BOOL CFX_DIBitmap::Create(int width, int height, FXDIB_Format format, uint8_t* pBuffer, int pitch) -{ - m_pBuffer = NULL; - m_bpp = (uint8_t)format; - m_AlphaFlag = (uint8_t)(format >> 8); - m_Width = m_Height = m_Pitch = 0; - if (width <= 0 || height <= 0 || pitch < 0) { - return FALSE; - } - if ((INT_MAX - 31) / width < (format & 0xff)) { - return FALSE; - } - if (!pitch) { - pitch = (width * (format & 0xff) + 31) / 32 * 4; - } - if ((1 << 30) / pitch < height) { +#define _MAX_OOM_LIMIT_ 12000000 +FX_BOOL CFX_DIBitmap::Create(int width, + int height, + FXDIB_Format format, + uint8_t* pBuffer, + int pitch) { + m_pBuffer = NULL; + m_bpp = (uint8_t)format; + m_AlphaFlag = (uint8_t)(format >> 8); + m_Width = m_Height = m_Pitch = 0; + if (width <= 0 || height <= 0 || pitch < 0) { + return FALSE; + } + if ((INT_MAX - 31) / width < (format & 0xff)) { + return FALSE; + } + if (!pitch) { + pitch = (width * (format & 0xff) + 31) / 32 * 4; + } + if ((1 << 30) / pitch < height) { + return FALSE; + } + if (pBuffer) { + m_pBuffer = pBuffer; + m_bExtBuf = TRUE; + } else { + int size = pitch * height + 4; + int oomlimit = _MAX_OOM_LIMIT_; + if (oomlimit >= 0 && size >= oomlimit) { + m_pBuffer = FX_TryAlloc(uint8_t, size); + if (m_pBuffer == NULL) { return FALSE; - } - if (pBuffer) { - m_pBuffer = pBuffer; - m_bExtBuf = TRUE; + } } else { - int size = pitch * height + 4; - int oomlimit = _MAX_OOM_LIMIT_; - if (oomlimit >= 0 && size >= oomlimit) { - m_pBuffer = FX_TryAlloc(uint8_t, size); - if (m_pBuffer == NULL) { - return FALSE; - } - } else { - m_pBuffer = FX_Alloc(uint8_t, size); - } + m_pBuffer = FX_Alloc(uint8_t, size); } - m_Width = width; - m_Height = height; - m_Pitch = pitch; - if (HasAlpha() && format != FXDIB_Argb) { - FX_BOOL ret = TRUE; - ret = BuildAlphaMask(); - if (!ret) { - if (!m_bExtBuf && m_pBuffer) { - FX_Free(m_pBuffer); - m_pBuffer = NULL; - m_Width = m_Height = m_Pitch = 0; - return FALSE; - } - } - } - return TRUE; -} -FX_BOOL CFX_DIBitmap::Copy(const CFX_DIBSource* pSrc) -{ - if (m_pBuffer) { - return FALSE; - } - if (!Create(pSrc->GetWidth(), pSrc->GetHeight(), pSrc->GetFormat())) { + } + m_Width = width; + m_Height = height; + m_Pitch = pitch; + if (HasAlpha() && format != FXDIB_Argb) { + FX_BOOL ret = TRUE; + ret = BuildAlphaMask(); + if (!ret) { + if (!m_bExtBuf && m_pBuffer) { + FX_Free(m_pBuffer); + m_pBuffer = NULL; + m_Width = m_Height = m_Pitch = 0; return FALSE; + } } - CopyPalette(pSrc->GetPalette()); - CopyAlphaMask(pSrc->m_pAlphaMask); - for (int row = 0; row < pSrc->GetHeight(); row ++) { - FXSYS_memcpy(m_pBuffer + row * m_Pitch, pSrc->GetScanline(row), m_Pitch); - } - return TRUE; + } + return TRUE; } -CFX_DIBitmap::~CFX_DIBitmap() -{ - if (m_pBuffer && !m_bExtBuf) { - FX_Free(m_pBuffer); - } - m_pBuffer = NULL; +FX_BOOL CFX_DIBitmap::Copy(const CFX_DIBSource* pSrc) { + if (m_pBuffer) { + return FALSE; + } + if (!Create(pSrc->GetWidth(), pSrc->GetHeight(), pSrc->GetFormat())) { + return FALSE; + } + CopyPalette(pSrc->GetPalette()); + CopyAlphaMask(pSrc->m_pAlphaMask); + for (int row = 0; row < pSrc->GetHeight(); row++) { + FXSYS_memcpy(m_pBuffer + row * m_Pitch, pSrc->GetScanline(row), m_Pitch); + } + return TRUE; } -void CFX_DIBitmap::TakeOver(CFX_DIBitmap* pSrcBitmap) -{ - if (m_pBuffer && !m_bExtBuf) { - FX_Free(m_pBuffer); - } - if (m_pPalette) { - FX_Free(m_pPalette); - } - delete m_pAlphaMask; - m_pBuffer = pSrcBitmap->m_pBuffer; - m_pPalette = pSrcBitmap->m_pPalette; - m_pAlphaMask = pSrcBitmap->m_pAlphaMask; - pSrcBitmap->m_pBuffer = NULL; - pSrcBitmap->m_pPalette = NULL; - pSrcBitmap->m_pAlphaMask = NULL; - m_bpp = pSrcBitmap->m_bpp; - m_bExtBuf = pSrcBitmap->m_bExtBuf; - m_AlphaFlag = pSrcBitmap->m_AlphaFlag; - m_Width = pSrcBitmap->m_Width; - m_Height = pSrcBitmap->m_Height; - m_Pitch = pSrcBitmap->m_Pitch; +CFX_DIBitmap::~CFX_DIBitmap() { + if (m_pBuffer && !m_bExtBuf) { + FX_Free(m_pBuffer); + } + m_pBuffer = NULL; } -CFX_DIBitmap* CFX_DIBSource::Clone(const FX_RECT* pClip) const -{ - FX_RECT rect(0, 0, m_Width, m_Height); - if (pClip) { - rect.Intersect(*pClip); - if (rect.IsEmpty()) { - return NULL; - } +void CFX_DIBitmap::TakeOver(CFX_DIBitmap* pSrcBitmap) { + if (m_pBuffer && !m_bExtBuf) { + FX_Free(m_pBuffer); + } + if (m_pPalette) { + FX_Free(m_pPalette); + } + delete m_pAlphaMask; + m_pBuffer = pSrcBitmap->m_pBuffer; + m_pPalette = pSrcBitmap->m_pPalette; + m_pAlphaMask = pSrcBitmap->m_pAlphaMask; + pSrcBitmap->m_pBuffer = NULL; + pSrcBitmap->m_pPalette = NULL; + pSrcBitmap->m_pAlphaMask = NULL; + m_bpp = pSrcBitmap->m_bpp; + m_bExtBuf = pSrcBitmap->m_bExtBuf; + m_AlphaFlag = pSrcBitmap->m_AlphaFlag; + m_Width = pSrcBitmap->m_Width; + m_Height = pSrcBitmap->m_Height; + m_Pitch = pSrcBitmap->m_Pitch; +} +CFX_DIBitmap* CFX_DIBSource::Clone(const FX_RECT* pClip) const { + FX_RECT rect(0, 0, m_Width, m_Height); + if (pClip) { + rect.Intersect(*pClip); + if (rect.IsEmpty()) { + return NULL; + } + } + CFX_DIBitmap* pNewBitmap = new CFX_DIBitmap; + if (!pNewBitmap->Create(rect.Width(), rect.Height(), GetFormat())) { + delete pNewBitmap; + return NULL; + } + pNewBitmap->CopyPalette(m_pPalette); + pNewBitmap->CopyAlphaMask(m_pAlphaMask, pClip); + if (GetBPP() == 1 && rect.left % 8 != 0) { + int left_shift = rect.left % 32; + int right_shift = 32 - left_shift; + int dword_count = pNewBitmap->m_Pitch / 4; + for (int row = rect.top; row < rect.bottom; row++) { + FX_DWORD* src_scan = (FX_DWORD*)GetScanline(row) + rect.left / 32; + FX_DWORD* dest_scan = (FX_DWORD*)pNewBitmap->GetScanline(row - rect.top); + for (int i = 0; i < dword_count; i++) { + dest_scan[i] = + (src_scan[i] << left_shift) | (src_scan[i + 1] >> right_shift); + } + } + } else { + int copy_len = (pNewBitmap->GetWidth() * pNewBitmap->GetBPP() + 7) / 8; + if (m_Pitch < (FX_DWORD)copy_len) { + copy_len = m_Pitch; + } + for (int row = rect.top; row < rect.bottom; row++) { + const uint8_t* src_scan = GetScanline(row) + rect.left * m_bpp / 8; + uint8_t* dest_scan = (uint8_t*)pNewBitmap->GetScanline(row - rect.top); + FXSYS_memcpy(dest_scan, src_scan, copy_len); + } + } + return pNewBitmap; +} +void CFX_DIBSource::BuildPalette() { + if (m_pPalette) { + return; + } + if (GetBPP() == 1) { + m_pPalette = FX_Alloc(FX_DWORD, 2); + if (IsCmykImage()) { + m_pPalette[0] = 0xff; + m_pPalette[1] = 0; + } else { + m_pPalette[0] = 0xff000000; + m_pPalette[1] = 0xffffffff; } - CFX_DIBitmap* pNewBitmap = new CFX_DIBitmap; - if (!pNewBitmap->Create(rect.Width(), rect.Height(), GetFormat())) { - delete pNewBitmap; - return NULL; - } - pNewBitmap->CopyPalette(m_pPalette); - pNewBitmap->CopyAlphaMask(m_pAlphaMask, pClip); - if (GetBPP() == 1 && rect.left % 8 != 0) { - int left_shift = rect.left % 32; - int right_shift = 32 - left_shift; - int dword_count = pNewBitmap->m_Pitch / 4; - for (int row = rect.top; row < rect.bottom; row ++) { - FX_DWORD* src_scan = (FX_DWORD*)GetScanline(row) + rect.left / 32; - FX_DWORD* dest_scan = (FX_DWORD*)pNewBitmap->GetScanline(row - rect.top); - for (int i = 0; i < dword_count; i ++) { - dest_scan[i] = (src_scan[i] << left_shift) | (src_scan[i + 1] >> right_shift); - } - } + } else if (GetBPP() == 8) { + m_pPalette = FX_Alloc(FX_DWORD, 256); + if (IsCmykImage()) { + for (int i = 0; i < 256; i++) { + m_pPalette[i] = 0xff - i; + } } else { - int copy_len = (pNewBitmap->GetWidth() * pNewBitmap->GetBPP() + 7) / 8; - if (m_Pitch < (FX_DWORD)copy_len) { - copy_len = m_Pitch; - } - for (int row = rect.top; row < rect.bottom; row ++) { - const uint8_t* src_scan = GetScanline(row) + rect.left * m_bpp / 8; - uint8_t* dest_scan = (uint8_t*)pNewBitmap->GetScanline(row - rect.top); - FXSYS_memcpy(dest_scan, src_scan, copy_len); - } + for (int i = 0; i < 256; i++) { + m_pPalette[i] = 0xff000000 | (i * 0x10101); + } } - return pNewBitmap; + } } -void CFX_DIBSource::BuildPalette() -{ - if (m_pPalette) { - return; - } +FX_BOOL CFX_DIBSource::BuildAlphaMask() { + if (m_pAlphaMask) { + return TRUE; + } + m_pAlphaMask = new CFX_DIBitmap; + if (!m_pAlphaMask->Create(m_Width, m_Height, FXDIB_8bppMask)) { + delete m_pAlphaMask; + m_pAlphaMask = NULL; + return FALSE; + } + FXSYS_memset(m_pAlphaMask->GetBuffer(), 0xff, + m_pAlphaMask->GetHeight() * m_pAlphaMask->GetPitch()); + return TRUE; +} +FX_DWORD CFX_DIBSource::GetPaletteEntry(int index) const { + ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask()); + if (m_pPalette) { + return m_pPalette[index]; + } + if (IsCmykImage()) { if (GetBPP() == 1) { - m_pPalette = FX_Alloc(FX_DWORD, 2); - if(IsCmykImage()) { - m_pPalette[0] = 0xff; - m_pPalette[1] = 0; - } else { - m_pPalette[0] = 0xff000000; - m_pPalette[1] = 0xffffffff; - } - } else if (GetBPP() == 8) { - m_pPalette = FX_Alloc(FX_DWORD, 256); - if(IsCmykImage()) { - for (int i = 0; i < 256; i ++) { - m_pPalette[i] = 0xff - i; - } - } else { - for (int i = 0; i < 256; i ++) { - m_pPalette[i] = 0xff000000 | (i * 0x10101); - } - } - } + return index ? 0 : 0xff; + } + return 0xff - index; + } + if (GetBPP() == 1) { + return index ? 0xffffffff : 0xff000000; + } + return index * 0x10101 | 0xff000000; } -FX_BOOL CFX_DIBSource::BuildAlphaMask() -{ - if (m_pAlphaMask) { - return TRUE; - } - m_pAlphaMask = new CFX_DIBitmap; - if (!m_pAlphaMask->Create(m_Width, m_Height, FXDIB_8bppMask)) { - delete m_pAlphaMask; - m_pAlphaMask = NULL; - return FALSE; - } - FXSYS_memset(m_pAlphaMask->GetBuffer(), 0xff, m_pAlphaMask->GetHeight()*m_pAlphaMask->GetPitch()); - return TRUE; +void CFX_DIBSource::SetPaletteEntry(int index, FX_DWORD color) { + ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask()); + if (m_pPalette == NULL) { + BuildPalette(); + } + m_pPalette[index] = color; } -FX_DWORD CFX_DIBSource::GetPaletteEntry(int index) const -{ - ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask()); - if (m_pPalette) { - return m_pPalette[index]; - } +int CFX_DIBSource::FindPalette(FX_DWORD color) const { + ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask()); + if (m_pPalette == NULL) { if (IsCmykImage()) { - if (GetBPP() == 1) { - return index ? 0 : 0xff; - } - return 0xff - index; + if (GetBPP() == 1) { + return ((uint8_t)color == 0xff) ? 0 : 1; + } + return 0xff - (uint8_t)color; } if (GetBPP() == 1) { - return index ? 0xffffffff : 0xff000000; + return ((uint8_t)color == 0xff) ? 1 : 0; } - return index * 0x10101 | 0xff000000; -} -void CFX_DIBSource::SetPaletteEntry(int index, FX_DWORD color) -{ - ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask()); - if (m_pPalette == NULL) { - BuildPalette(); + return (uint8_t)color; + } + int palsize = (1 << GetBPP()); + for (int i = 0; i < palsize; i++) + if (m_pPalette[i] == color) { + return i; } - m_pPalette[index] = color; + return -1; } -int CFX_DIBSource::FindPalette(FX_DWORD color) const -{ - ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask()); - if (m_pPalette == NULL) { - if (IsCmykImage()) { - if (GetBPP() == 1) { - return ((uint8_t)color == 0xff) ? 0 : 1; - } - return 0xff - (uint8_t)color; - } - if (GetBPP() == 1) { - return ((uint8_t)color == 0xff) ? 1 : 0; - } - return (uint8_t)color; - } - int palsize = (1 << GetBPP()); - for (int i = 0; i < palsize; i ++) - if (m_pPalette[i] == color) { - return i; - } - return -1; +void CFX_DIBitmap::Clear(FX_DWORD color) { + if (m_pBuffer == NULL) { + return; + } + switch (GetFormat()) { + case FXDIB_1bppMask: + FXSYS_memset(m_pBuffer, (color & 0xff000000) ? 0xff : 0, + m_Pitch * m_Height); + break; + case FXDIB_1bppRgb: { + int index = FindPalette(color); + FXSYS_memset(m_pBuffer, index ? 0xff : 0, m_Pitch * m_Height); + break; + } + case FXDIB_8bppMask: + FXSYS_memset(m_pBuffer, color >> 24, m_Pitch * m_Height); + break; + case FXDIB_8bppRgb: { + int index = FindPalette(color); + FXSYS_memset(m_pBuffer, index, m_Pitch * m_Height); + break; + } + case FXDIB_Rgb: + case FXDIB_Rgba: { + int a, r, g, b; + ArgbDecode(color, a, r, g, b); + if (r == g && g == b) { + FXSYS_memset(m_pBuffer, r, m_Pitch * m_Height); + } else { + int byte_pos = 0; + for (int col = 0; col < m_Width; col++) { + m_pBuffer[byte_pos++] = b; + m_pBuffer[byte_pos++] = g; + m_pBuffer[byte_pos++] = r; + } + for (int row = 1; row < m_Height; row++) { + FXSYS_memcpy(m_pBuffer + row * m_Pitch, m_pBuffer, m_Pitch); + } + } + break; + } + case FXDIB_Rgb32: + case FXDIB_Argb: { + color = IsCmykImage() ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); + for (int i = 0; i < m_Width; i++) { + ((FX_DWORD*)m_pBuffer)[i] = color; + } + for (int row = 1; row < m_Height; row++) { + FXSYS_memcpy(m_pBuffer + row * m_Pitch, m_pBuffer, m_Pitch); + } + break; + } + default: + break; + } } -void CFX_DIBitmap::Clear(FX_DWORD color) -{ - if (m_pBuffer == NULL) { - return; - } - switch (GetFormat()) { - case FXDIB_1bppMask: - FXSYS_memset(m_pBuffer, (color & 0xff000000) ? 0xff : 0, m_Pitch * m_Height); - break; - case FXDIB_1bppRgb: { - int index = FindPalette(color); - FXSYS_memset(m_pBuffer, index ? 0xff : 0, m_Pitch * m_Height); - break; - } - case FXDIB_8bppMask: - FXSYS_memset(m_pBuffer, color >> 24, m_Pitch * m_Height); - break; - case FXDIB_8bppRgb: { - int index = FindPalette(color); - FXSYS_memset(m_pBuffer, index, m_Pitch * m_Height); - break; - } - case FXDIB_Rgb: - case FXDIB_Rgba: { - int a, r, g, b; - ArgbDecode(color, a, r, g, b); - if (r == g && g == b) { - FXSYS_memset(m_pBuffer, r, m_Pitch * m_Height); - } else { - int byte_pos = 0; - for (int col = 0; col < m_Width; col ++) { - m_pBuffer[byte_pos++] = b; - m_pBuffer[byte_pos++] = g; - m_pBuffer[byte_pos++] = r; - } - for (int row = 1; row < m_Height; row ++) { - FXSYS_memcpy(m_pBuffer + row * m_Pitch, m_pBuffer, m_Pitch); - } - } - break; - } - case FXDIB_Rgb32: - case FXDIB_Argb: { - color = IsCmykImage() ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); - for (int i = 0; i < m_Width; i ++) { - ((FX_DWORD*)m_pBuffer)[i] = color; - } - for (int row = 1; row < m_Height; row ++) { - FXSYS_memcpy(m_pBuffer + row * m_Pitch, m_pBuffer, m_Pitch); - } - break; - } - default: - break; - } +void CFX_DIBSource::GetOverlapRect(int& dest_left, + int& dest_top, + int& width, + int& height, + int src_width, + int src_height, + int& src_left, + int& src_top, + const CFX_ClipRgn* pClipRgn) { + if (width == 0 || height == 0) { + return; + } + ASSERT(width > 0 && height > 0); + if (dest_left > m_Width || dest_top > m_Height) { + width = 0; + height = 0; + return; + } + int x_offset = dest_left - src_left; + int y_offset = dest_top - src_top; + FX_RECT src_rect(src_left, src_top, src_left + width, src_top + height); + FX_RECT src_bound(0, 0, src_width, src_height); + src_rect.Intersect(src_bound); + FX_RECT dest_rect(src_rect.left + x_offset, src_rect.top + y_offset, + src_rect.right + x_offset, src_rect.bottom + y_offset); + FX_RECT dest_bound(0, 0, m_Width, m_Height); + dest_rect.Intersect(dest_bound); + if (pClipRgn) { + dest_rect.Intersect(pClipRgn->GetBox()); + } + dest_left = dest_rect.left; + dest_top = dest_rect.top; + src_left = dest_left - x_offset; + src_top = dest_top - y_offset; + width = dest_rect.right - dest_rect.left; + height = dest_rect.bottom - dest_rect.top; } -void CFX_DIBSource::GetOverlapRect(int& dest_left, int& dest_top, int& width, int& height, - int src_width, int src_height, int& src_left, int& src_top, - const CFX_ClipRgn* pClipRgn) -{ - if (width == 0 || height == 0) { - return; - } - ASSERT(width > 0 && height > 0); - if (dest_left > m_Width || dest_top > m_Height) { - width = 0; - height = 0; - return; - } - int x_offset = dest_left - src_left; - int y_offset = dest_top - src_top; - FX_RECT src_rect(src_left, src_top, src_left + width, src_top + height); - FX_RECT src_bound(0, 0, src_width, src_height); - src_rect.Intersect(src_bound); - FX_RECT dest_rect(src_rect.left + x_offset, src_rect.top + y_offset, - src_rect.right + x_offset, src_rect.bottom + y_offset); - FX_RECT dest_bound(0, 0, m_Width, m_Height); - dest_rect.Intersect(dest_bound); - if (pClipRgn) { - dest_rect.Intersect(pClipRgn->GetBox()); - } - dest_left = dest_rect.left; - dest_top = dest_rect.top; - src_left = dest_left - x_offset; - src_top = dest_top - y_offset; - width = dest_rect.right - dest_rect.left; - height = dest_rect.bottom - dest_rect.top; -} -FX_BOOL CFX_DIBitmap::TransferBitmap(int dest_left, int dest_top, int width, int height, - const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform) -{ - if (m_pBuffer == NULL) { - return FALSE; - } - GetOverlapRect(dest_left, dest_top, width, height, pSrcBitmap->GetWidth(), pSrcBitmap->GetHeight(), src_left, src_top, NULL); - if (width == 0 || height == 0) { - return TRUE; - } - FXDIB_Format dest_format = GetFormat(); - FXDIB_Format src_format = pSrcBitmap->GetFormat(); - if (dest_format == src_format && pIccTransform == NULL) { - if (GetBPP() == 1) { - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = m_pBuffer + (dest_top + row) * m_Pitch; - const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row); - for (int col = 0; col < width; col ++) { - if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) { - dest_scan[(dest_left + col) / 8] |= 1 << (7 - (dest_left + col) % 8); - } else { - dest_scan[(dest_left + col) / 8] &= ~(1 << (7 - (dest_left + col) % 8)); - } - } - } - } else { - int Bpp = GetBPP() / 8; - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = m_pBuffer + (dest_top + row) * m_Pitch + dest_left * Bpp; - const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * Bpp; - FXSYS_memcpy(dest_scan, src_scan, width * Bpp); - } - } - } else { - if (m_pPalette) { - return FALSE; - } - if (m_bpp == 8) { - dest_format = FXDIB_8bppMask; - } - uint8_t* dest_buf = m_pBuffer + dest_top * m_Pitch + dest_left * GetBPP() / 8; - FX_DWORD* d_plt = NULL; - if(!ConvertBuffer(dest_format, dest_buf, m_Pitch, width, height, pSrcBitmap, src_left, src_top, d_plt, pIccTransform)) { - return FALSE; - } - } +FX_BOOL CFX_DIBitmap::TransferBitmap(int dest_left, + int dest_top, + int width, + int height, + const CFX_DIBSource* pSrcBitmap, + int src_left, + int src_top, + void* pIccTransform) { + if (m_pBuffer == NULL) { + return FALSE; + } + GetOverlapRect(dest_left, dest_top, width, height, pSrcBitmap->GetWidth(), + pSrcBitmap->GetHeight(), src_left, src_top, NULL); + if (width == 0 || height == 0) { return TRUE; -} -FX_BOOL CFX_DIBitmap::TransferMask(int dest_left, int dest_top, int width, int height, - const CFX_DIBSource* pMask, FX_DWORD color, int src_left, int src_top, int alpha_flag, void* pIccTransform) -{ - if (m_pBuffer == NULL) { - return FALSE; - } - ASSERT(HasAlpha() && (m_bpp >= 24)); - ASSERT(pMask->IsAlphaMask()); - if (!HasAlpha() || !pMask->IsAlphaMask() || m_bpp < 24) { - return FALSE; - } - GetOverlapRect(dest_left, dest_top, width, height, pMask->GetWidth(), pMask->GetHeight(), src_left, src_top, NULL); - if (width == 0 || height == 0) { - return TRUE; - } - int src_bpp = pMask->GetBPP(); - int alpha; - FX_DWORD dst_color; - if (alpha_flag >> 8) { - alpha = alpha_flag & 0xff; - dst_color = FXCMYK_TODIB(color); - } else { - alpha = FXARGB_A(color); - dst_color = FXARGB_TODIB(color); - } - uint8_t* color_p = (uint8_t*)&dst_color; - if (pIccTransform && CFX_GEModule::Get()->GetCodecModule() && CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) { - ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - pIccModule->TranslateScanline(pIccTransform, color_p, color_p, 1); + } + FXDIB_Format dest_format = GetFormat(); + FXDIB_Format src_format = pSrcBitmap->GetFormat(); + if (dest_format == src_format && pIccTransform == NULL) { + if (GetBPP() == 1) { + for (int row = 0; row < height; row++) { + uint8_t* dest_scan = m_pBuffer + (dest_top + row) * m_Pitch; + const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row); + for (int col = 0; col < width; col++) { + if (src_scan[(src_left + col) / 8] & + (1 << (7 - (src_left + col) % 8))) { + dest_scan[(dest_left + col) / 8] |= 1 + << (7 - (dest_left + col) % 8); + } else { + dest_scan[(dest_left + col) / 8] &= + ~(1 << (7 - (dest_left + col) % 8)); + } + } + } } else { - if (alpha_flag >> 8 && !IsCmykImage()) - AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), FXSYS_GetYValue(color), FXSYS_GetKValue(color), - color_p[2], color_p[1], color_p[0]); - else if (!(alpha_flag >> 8) && IsCmykImage()) { - return FALSE; - } + int Bpp = GetBPP() / 8; + for (int row = 0; row < height; row++) { + uint8_t* dest_scan = + m_pBuffer + (dest_top + row) * m_Pitch + dest_left * Bpp; + const uint8_t* src_scan = + pSrcBitmap->GetScanline(src_top + row) + src_left * Bpp; + FXSYS_memcpy(dest_scan, src_scan, width * Bpp); + } + } + } else { + if (m_pPalette) { + return FALSE; } - if(!IsCmykImage()) { - color_p[3] = (uint8_t)alpha; + if (m_bpp == 8) { + dest_format = FXDIB_8bppMask; } - if (GetFormat() == FXDIB_Argb) { - for (int row = 0; row < height; row ++) { - FX_DWORD* dest_pos = (FX_DWORD*)(m_pBuffer + (dest_top + row) * m_Pitch + dest_left * 4); - const uint8_t* src_scan = pMask->GetScanline(src_top + row); - if (src_bpp == 1) { - for (int col = 0; col < width; col ++) { - int src_bitpos = src_left + col; - if (src_scan[src_bitpos / 8] & (1 << (7 - src_bitpos % 8))) { - *dest_pos = dst_color; - } else { - *dest_pos = 0; - } - dest_pos ++; - } - } else { - src_scan += src_left; - dst_color = FXARGB_TODIB(dst_color); - dst_color &= 0xffffff; - for (int col = 0; col < width; col ++) { - FXARGB_SETDIB(dest_pos++, dst_color | ((alpha * (*src_scan++) / 255) << 24)); - } - } - } - } else { - int comps = m_bpp / 8; - for (int row = 0; row < height; row ++) { - uint8_t* dest_color_pos = m_pBuffer + (dest_top + row) * m_Pitch + dest_left * comps; - uint8_t* dest_alpha_pos = (uint8_t*)m_pAlphaMask->GetScanline(dest_top + row) + dest_left; - const uint8_t* src_scan = pMask->GetScanline(src_top + row); - if (src_bpp == 1) { - for (int col = 0; col < width; col ++) { - int src_bitpos = src_left + col; - if (src_scan[src_bitpos / 8] & (1 << (7 - src_bitpos % 8))) { - FXSYS_memcpy(dest_color_pos, color_p, comps); - *dest_alpha_pos = 0xff; - } else { - FXSYS_memset(dest_color_pos, 0, comps); - *dest_alpha_pos = 0; - } - dest_color_pos += comps; - dest_alpha_pos ++; - } - } else { - src_scan += src_left; - for (int col = 0; col < width; col ++) { - FXSYS_memcpy(dest_color_pos, color_p, comps); - dest_color_pos += comps; - *dest_alpha_pos++ = (alpha * (*src_scan++) / 255); - } - } - } + uint8_t* dest_buf = + m_pBuffer + dest_top * m_Pitch + dest_left * GetBPP() / 8; + FX_DWORD* d_plt = NULL; + if (!ConvertBuffer(dest_format, dest_buf, m_Pitch, width, height, + pSrcBitmap, src_left, src_top, d_plt, pIccTransform)) { + return FALSE; } - return TRUE; + } + return TRUE; } -void CFX_DIBSource::CopyPalette(const FX_DWORD* pSrc, FX_DWORD size) -{ - if (pSrc == NULL || GetBPP() > 8) { - if (m_pPalette) { - FX_Free(m_pPalette); - } - m_pPalette = NULL; - } else { - FX_DWORD pal_size = 1 << GetBPP(); - if (m_pPalette == NULL) { - m_pPalette = FX_Alloc(FX_DWORD, pal_size); - } - if (pal_size > size) { - pal_size = size; - } - FXSYS_memcpy(m_pPalette, pSrc, pal_size * sizeof(FX_DWORD)); - } +FX_BOOL CFX_DIBitmap::TransferMask(int dest_left, + int dest_top, + int width, + int height, + const CFX_DIBSource* pMask, + FX_DWORD color, + int src_left, + int src_top, + int alpha_flag, + void* pIccTransform) { + if (m_pBuffer == NULL) { + return FALSE; + } + ASSERT(HasAlpha() && (m_bpp >= 24)); + ASSERT(pMask->IsAlphaMask()); + if (!HasAlpha() || !pMask->IsAlphaMask() || m_bpp < 24) { + return FALSE; + } + GetOverlapRect(dest_left, dest_top, width, height, pMask->GetWidth(), + pMask->GetHeight(), src_left, src_top, NULL); + if (width == 0 || height == 0) { + return TRUE; + } + int src_bpp = pMask->GetBPP(); + int alpha; + FX_DWORD dst_color; + if (alpha_flag >> 8) { + alpha = alpha_flag & 0xff; + dst_color = FXCMYK_TODIB(color); + } else { + alpha = FXARGB_A(color); + dst_color = FXARGB_TODIB(color); + } + uint8_t* color_p = (uint8_t*)&dst_color; + if (pIccTransform && CFX_GEModule::Get()->GetCodecModule() && + CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) { + ICodec_IccModule* pIccModule = + CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + pIccModule->TranslateScanline(pIccTransform, color_p, color_p, 1); + } else { + if (alpha_flag >> 8 && !IsCmykImage()) + AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), + FXSYS_GetYValue(color), FXSYS_GetKValue(color), + color_p[2], color_p[1], color_p[0]); + else if (!(alpha_flag >> 8) && IsCmykImage()) { + return FALSE; + } + } + if (!IsCmykImage()) { + color_p[3] = (uint8_t)alpha; + } + if (GetFormat() == FXDIB_Argb) { + for (int row = 0; row < height; row++) { + FX_DWORD* dest_pos = + (FX_DWORD*)(m_pBuffer + (dest_top + row) * m_Pitch + dest_left * 4); + const uint8_t* src_scan = pMask->GetScanline(src_top + row); + if (src_bpp == 1) { + for (int col = 0; col < width; col++) { + int src_bitpos = src_left + col; + if (src_scan[src_bitpos / 8] & (1 << (7 - src_bitpos % 8))) { + *dest_pos = dst_color; + } else { + *dest_pos = 0; + } + dest_pos++; + } + } else { + src_scan += src_left; + dst_color = FXARGB_TODIB(dst_color); + dst_color &= 0xffffff; + for (int col = 0; col < width; col++) { + FXARGB_SETDIB(dest_pos++, + dst_color | ((alpha * (*src_scan++) / 255) << 24)); + } + } + } + } else { + int comps = m_bpp / 8; + for (int row = 0; row < height; row++) { + uint8_t* dest_color_pos = + m_pBuffer + (dest_top + row) * m_Pitch + dest_left * comps; + uint8_t* dest_alpha_pos = + (uint8_t*)m_pAlphaMask->GetScanline(dest_top + row) + dest_left; + const uint8_t* src_scan = pMask->GetScanline(src_top + row); + if (src_bpp == 1) { + for (int col = 0; col < width; col++) { + int src_bitpos = src_left + col; + if (src_scan[src_bitpos / 8] & (1 << (7 - src_bitpos % 8))) { + FXSYS_memcpy(dest_color_pos, color_p, comps); + *dest_alpha_pos = 0xff; + } else { + FXSYS_memset(dest_color_pos, 0, comps); + *dest_alpha_pos = 0; + } + dest_color_pos += comps; + dest_alpha_pos++; + } + } else { + src_scan += src_left; + for (int col = 0; col < width; col++) { + FXSYS_memcpy(dest_color_pos, color_p, comps); + dest_color_pos += comps; + *dest_alpha_pos++ = (alpha * (*src_scan++) / 255); + } + } + } + } + return TRUE; } -void CFX_DIBSource::GetPalette(FX_DWORD* pal, int alpha) const -{ - ASSERT(GetBPP() <= 8 && !IsCmykImage()); - if (GetBPP() == 1) { - pal[0] = ((m_pPalette ? m_pPalette[0] : 0xff000000) & 0xffffff) | (alpha << 24); - pal[1] = ((m_pPalette ? m_pPalette[1] : 0xffffffff) & 0xffffff) | (alpha << 24); - return; - } +void CFX_DIBSource::CopyPalette(const FX_DWORD* pSrc, FX_DWORD size) { + if (pSrc == NULL || GetBPP() > 8) { if (m_pPalette) { - for (int i = 0; i < 256; i ++) { - pal[i] = (m_pPalette[i] & 0x00ffffff) | (alpha << 24); - } - } else { - for (int i = 0; i < 256; i ++) { - pal[i] = (i * 0x10101) | (alpha << 24); - } + FX_Free(m_pPalette); } -} -CFX_DIBitmap* CFX_DIBSource::GetAlphaMask(const FX_RECT* pClip) const -{ - ASSERT(GetFormat() == FXDIB_Argb); - FX_RECT rect(0, 0, m_Width, m_Height); - if (pClip) { - rect.Intersect(*pClip); - if (rect.IsEmpty()) { - return NULL; - } + m_pPalette = NULL; + } else { + FX_DWORD pal_size = 1 << GetBPP(); + if (m_pPalette == NULL) { + m_pPalette = FX_Alloc(FX_DWORD, pal_size); } - CFX_DIBitmap* pMask = new CFX_DIBitmap; - if (!pMask->Create(rect.Width(), rect.Height(), FXDIB_8bppMask)) { - delete pMask; - return NULL; - } - for (int row = rect.top; row < rect.bottom; row ++) { - const uint8_t* src_scan = GetScanline(row) + rect.left * 4 + 3; - uint8_t* dest_scan = (uint8_t*)pMask->GetScanline(row - rect.top); - for (int col = rect.left; col < rect.right; col ++) { - *dest_scan ++ = *src_scan; - src_scan += 4; - } + if (pal_size > size) { + pal_size = size; } - return pMask; + FXSYS_memcpy(m_pPalette, pSrc, pal_size * sizeof(FX_DWORD)); + } +} +void CFX_DIBSource::GetPalette(FX_DWORD* pal, int alpha) const { + ASSERT(GetBPP() <= 8 && !IsCmykImage()); + if (GetBPP() == 1) { + pal[0] = + ((m_pPalette ? m_pPalette[0] : 0xff000000) & 0xffffff) | (alpha << 24); + pal[1] = + ((m_pPalette ? m_pPalette[1] : 0xffffffff) & 0xffffff) | (alpha << 24); + return; + } + if (m_pPalette) { + for (int i = 0; i < 256; i++) { + pal[i] = (m_pPalette[i] & 0x00ffffff) | (alpha << 24); + } + } else { + for (int i = 0; i < 256; i++) { + pal[i] = (i * 0x10101) | (alpha << 24); + } + } } -FX_BOOL CFX_DIBSource::CopyAlphaMask(const CFX_DIBSource* pAlphaMask, const FX_RECT* pClip) -{ - if (!HasAlpha() || GetFormat() == FXDIB_Argb) { +CFX_DIBitmap* CFX_DIBSource::GetAlphaMask(const FX_RECT* pClip) const { + ASSERT(GetFormat() == FXDIB_Argb); + FX_RECT rect(0, 0, m_Width, m_Height); + if (pClip) { + rect.Intersect(*pClip); + if (rect.IsEmpty()) { + return NULL; + } + } + CFX_DIBitmap* pMask = new CFX_DIBitmap; + if (!pMask->Create(rect.Width(), rect.Height(), FXDIB_8bppMask)) { + delete pMask; + return NULL; + } + for (int row = rect.top; row < rect.bottom; row++) { + const uint8_t* src_scan = GetScanline(row) + rect.left * 4 + 3; + uint8_t* dest_scan = (uint8_t*)pMask->GetScanline(row - rect.top); + for (int col = rect.left; col < rect.right; col++) { + *dest_scan++ = *src_scan; + src_scan += 4; + } + } + return pMask; +} +FX_BOOL CFX_DIBSource::CopyAlphaMask(const CFX_DIBSource* pAlphaMask, + const FX_RECT* pClip) { + if (!HasAlpha() || GetFormat() == FXDIB_Argb) { + return FALSE; + } + if (pAlphaMask) { + FX_RECT rect(0, 0, pAlphaMask->m_Width, pAlphaMask->m_Height); + if (pClip) { + rect.Intersect(*pClip); + if (rect.IsEmpty() || rect.Width() != m_Width || + rect.Height() != m_Height) { return FALSE; - } - if (pAlphaMask) { - FX_RECT rect(0, 0, pAlphaMask->m_Width, pAlphaMask->m_Height); - if (pClip) { - rect.Intersect(*pClip); - if (rect.IsEmpty() || rect.Width() != m_Width || rect.Height() != m_Height) { - return FALSE; - } - } else { - if (pAlphaMask->m_Width != m_Width || pAlphaMask->m_Height != m_Height) { - return FALSE; - } - } - for (int row = 0; row < m_Height; row ++) - FXSYS_memcpy((void*)m_pAlphaMask->GetScanline(row), - pAlphaMask->GetScanline(row + rect.top) + rect.left, m_pAlphaMask->m_Pitch); + } } else { - m_pAlphaMask->Clear(0xff000000); - } - return TRUE; + if (pAlphaMask->m_Width != m_Width || pAlphaMask->m_Height != m_Height) { + return FALSE; + } + } + for (int row = 0; row < m_Height; row++) + FXSYS_memcpy((void*)m_pAlphaMask->GetScanline(row), + pAlphaMask->GetScanline(row + rect.top) + rect.left, + m_pAlphaMask->m_Pitch); + } else { + m_pAlphaMask->Clear(0xff000000); + } + return TRUE; } const int g_ChannelOffset[] = {0, 2, 1, 0, 0, 1, 2, 3, 3}; -FX_BOOL CFX_DIBitmap::LoadChannel(FXDIB_Channel destChannel, const CFX_DIBSource* pSrcBitmap, FXDIB_Channel srcChannel) -{ - if (m_pBuffer == NULL) { +FX_BOOL CFX_DIBitmap::LoadChannel(FXDIB_Channel destChannel, + const CFX_DIBSource* pSrcBitmap, + FXDIB_Channel srcChannel) { + if (m_pBuffer == NULL) { + return FALSE; + } + CFX_DIBSource* pSrcClone = (CFX_DIBSource*)pSrcBitmap; + CFX_DIBitmap* pDst = this; + int destOffset, srcOffset; + if (srcChannel == FXDIB_Alpha) { + if (!pSrcBitmap->HasAlpha() && !pSrcBitmap->IsAlphaMask()) { + return FALSE; + } + if (pSrcBitmap->GetBPP() == 1) { + pSrcClone = pSrcBitmap->CloneConvert(FXDIB_8bppMask); + if (pSrcClone == NULL) { return FALSE; + } } - CFX_DIBSource* pSrcClone = (CFX_DIBSource*)pSrcBitmap; - CFX_DIBitmap* pDst = this; - int destOffset, srcOffset; - if (srcChannel == FXDIB_Alpha) { - if (!pSrcBitmap->HasAlpha() && !pSrcBitmap->IsAlphaMask()) { - return FALSE; - } - if (pSrcBitmap->GetBPP() == 1) { - pSrcClone = pSrcBitmap->CloneConvert(FXDIB_8bppMask); - if (pSrcClone == NULL) { - return FALSE; - } - } - if(pSrcBitmap->GetFormat() == FXDIB_Argb) { - srcOffset = 3; - } else { - srcOffset = 0; - } - } else { - if (pSrcBitmap->IsAlphaMask()) { - return FALSE; - } - if (pSrcBitmap->GetBPP() < 24) { - if (pSrcBitmap->IsCmykImage()) { - pSrcClone = pSrcBitmap->CloneConvert((FXDIB_Format)((pSrcBitmap->GetFormat() & 0xff00) | 0x20)); - } else { - pSrcClone = pSrcBitmap->CloneConvert((FXDIB_Format)((pSrcBitmap->GetFormat() & 0xff00) | 0x18)); - } - if (pSrcClone == NULL) { - return FALSE; - } - } - srcOffset = g_ChannelOffset[srcChannel]; - } - if (destChannel == FXDIB_Alpha) { - if (IsAlphaMask()) { - if(!ConvertFormat(FXDIB_8bppMask)) { - if (pSrcClone != pSrcBitmap) { - delete pSrcClone; - } - return FALSE; - } - destOffset = 0; - } else { - destOffset = 0; - if(!ConvertFormat(IsCmykImage() ? FXDIB_Cmyka : FXDIB_Argb)) { - if (pSrcClone != pSrcBitmap) { - delete pSrcClone; - } - return FALSE; - } - if (GetFormat() == FXDIB_Argb) { - destOffset = 3; - } - } + if (pSrcBitmap->GetFormat() == FXDIB_Argb) { + srcOffset = 3; } else { - if (IsAlphaMask()) { - if (pSrcClone != pSrcBitmap) { - delete pSrcClone; - } - return FALSE; - } - if (GetBPP() < 24) { - if (HasAlpha()) { - if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyka : FXDIB_Argb)) { - if (pSrcClone != pSrcBitmap) { - delete pSrcClone; - } - return FALSE; - } - } else -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyk : FXDIB_Rgb32)) { -#else - if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyk : FXDIB_Rgb)) { -#endif - if (pSrcClone != pSrcBitmap) { - delete pSrcClone; - } - return FALSE; - } - } - destOffset = g_ChannelOffset[destChannel]; - } - if (srcChannel == FXDIB_Alpha && pSrcClone->m_pAlphaMask) { - CFX_DIBitmap* pAlphaMask = pSrcClone->m_pAlphaMask; - if (pSrcClone->GetWidth() != m_Width || pSrcClone->GetHeight() != m_Height) { - if (pAlphaMask) { - pAlphaMask = pAlphaMask->StretchTo(m_Width, m_Height); - if (pAlphaMask == NULL) { - if (pSrcClone != pSrcBitmap) { - delete pSrcClone; - } - return FALSE; - } - } - } + srcOffset = 0; + } + } else { + if (pSrcBitmap->IsAlphaMask()) { + return FALSE; + } + if (pSrcBitmap->GetBPP() < 24) { + if (pSrcBitmap->IsCmykImage()) { + pSrcClone = pSrcBitmap->CloneConvert( + (FXDIB_Format)((pSrcBitmap->GetFormat() & 0xff00) | 0x20)); + } else { + pSrcClone = pSrcBitmap->CloneConvert( + (FXDIB_Format)((pSrcBitmap->GetFormat() & 0xff00) | 0x18)); + } + if (pSrcClone == NULL) { + return FALSE; + } + } + srcOffset = g_ChannelOffset[srcChannel]; + } + if (destChannel == FXDIB_Alpha) { + if (IsAlphaMask()) { + if (!ConvertFormat(FXDIB_8bppMask)) { if (pSrcClone != pSrcBitmap) { - pSrcClone->m_pAlphaMask = NULL; - delete pSrcClone; + delete pSrcClone; } - pSrcClone = pAlphaMask; - srcOffset = 0; - } else if (pSrcClone->GetWidth() != m_Width || pSrcClone->GetHeight() != m_Height) { - CFX_DIBitmap* pSrcMatched = pSrcClone->StretchTo(m_Width, m_Height); + return FALSE; + } + destOffset = 0; + } else { + destOffset = 0; + if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyka : FXDIB_Argb)) { if (pSrcClone != pSrcBitmap) { - delete pSrcClone; - } - if (pSrcMatched == NULL) { - return FALSE; - } - pSrcClone = pSrcMatched; - } - if (destChannel == FXDIB_Alpha && m_pAlphaMask) { - pDst = m_pAlphaMask; - destOffset = 0; - } - int srcBytes = pSrcClone->GetBPP() / 8; - int destBytes = pDst->GetBPP() / 8; - for (int row = 0; row < m_Height; row ++) { - uint8_t* dest_pos = (uint8_t*)pDst->GetScanline(row) + destOffset; - const uint8_t* src_pos = pSrcClone->GetScanline(row) + srcOffset; - for (int col = 0; col < m_Width; col ++) { - *dest_pos = *src_pos; - dest_pos += destBytes; - src_pos += srcBytes; + delete pSrcClone; } + return FALSE; + } + if (GetFormat() == FXDIB_Argb) { + destOffset = 3; + } } - if (pSrcClone != pSrcBitmap && pSrcClone != pSrcBitmap->m_pAlphaMask) { + } else { + if (IsAlphaMask()) { + if (pSrcClone != pSrcBitmap) { delete pSrcClone; + } + return FALSE; } - return TRUE; -} -FX_BOOL CFX_DIBitmap::LoadChannel(FXDIB_Channel destChannel, int value) -{ - if (m_pBuffer == NULL) { - return FALSE; - } - int destOffset; - if (destChannel == FXDIB_Alpha) { - if (IsAlphaMask()) { - if(!ConvertFormat(FXDIB_8bppMask)) { - return FALSE; - } - destOffset = 0; - } else { - destOffset = 0; - if(!ConvertFormat(IsCmykImage() ? FXDIB_Cmyka : FXDIB_Argb)) { - return FALSE; - } - if (GetFormat() == FXDIB_Argb) { - destOffset = 3; - } - } - } else { - if (IsAlphaMask()) { - return FALSE; + if (GetBPP() < 24) { + if (HasAlpha()) { + if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyka : FXDIB_Argb)) { + if (pSrcClone != pSrcBitmap) { + delete pSrcClone; + } + return FALSE; } - if (GetBPP() < 24) { - if (HasAlpha()) { - if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyka : FXDIB_Argb)) { - return FALSE; - } - } else -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyk : FXDIB_Rgb)) { - return FALSE; - } + } else +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyk : FXDIB_Rgb32)) { #else - if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyk : FXDIB_Rgb32)) { - return FALSE; - } + if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyk : FXDIB_Rgb)) { #endif + if (pSrcClone != pSrcBitmap) { + delete pSrcClone; } - destOffset = g_ChannelOffset[destChannel]; - } - int Bpp = GetBPP() / 8; - if (Bpp == 1) { - FXSYS_memset(m_pBuffer, value, m_Height * m_Pitch); - return TRUE; - } - if (destChannel == FXDIB_Alpha && m_pAlphaMask) { - FXSYS_memset(m_pAlphaMask->GetBuffer(), value, m_pAlphaMask->GetHeight()*m_pAlphaMask->GetPitch()); - return TRUE; - } - for (int row = 0; row < m_Height; row ++) { - uint8_t* scan_line = m_pBuffer + row * m_Pitch + destOffset; - for (int col = 0; col < m_Width; col ++) { - *scan_line = value; - scan_line += Bpp; + return FALSE; + } + } + destOffset = g_ChannelOffset[destChannel]; + } + if (srcChannel == FXDIB_Alpha && pSrcClone->m_pAlphaMask) { + CFX_DIBitmap* pAlphaMask = pSrcClone->m_pAlphaMask; + if (pSrcClone->GetWidth() != m_Width || + pSrcClone->GetHeight() != m_Height) { + if (pAlphaMask) { + pAlphaMask = pAlphaMask->StretchTo(m_Width, m_Height); + if (pAlphaMask == NULL) { + if (pSrcClone != pSrcBitmap) { + delete pSrcClone; + } + return FALSE; } + } } - return TRUE; + if (pSrcClone != pSrcBitmap) { + pSrcClone->m_pAlphaMask = NULL; + delete pSrcClone; + } + pSrcClone = pAlphaMask; + srcOffset = 0; + } else if (pSrcClone->GetWidth() != m_Width || + pSrcClone->GetHeight() != m_Height) { + CFX_DIBitmap* pSrcMatched = pSrcClone->StretchTo(m_Width, m_Height); + if (pSrcClone != pSrcBitmap) { + delete pSrcClone; + } + if (pSrcMatched == NULL) { + return FALSE; + } + pSrcClone = pSrcMatched; + } + if (destChannel == FXDIB_Alpha && m_pAlphaMask) { + pDst = m_pAlphaMask; + destOffset = 0; + } + int srcBytes = pSrcClone->GetBPP() / 8; + int destBytes = pDst->GetBPP() / 8; + for (int row = 0; row < m_Height; row++) { + uint8_t* dest_pos = (uint8_t*)pDst->GetScanline(row) + destOffset; + const uint8_t* src_pos = pSrcClone->GetScanline(row) + srcOffset; + for (int col = 0; col < m_Width; col++) { + *dest_pos = *src_pos; + dest_pos += destBytes; + src_pos += srcBytes; + } + } + if (pSrcClone != pSrcBitmap && pSrcClone != pSrcBitmap->m_pAlphaMask) { + delete pSrcClone; + } + return TRUE; } -FX_BOOL CFX_DIBitmap::MultiplyAlpha(const CFX_DIBSource* pSrcBitmap) -{ - if (m_pBuffer == NULL) { +FX_BOOL CFX_DIBitmap::LoadChannel(FXDIB_Channel destChannel, int value) { + if (m_pBuffer == NULL) { + return FALSE; + } + int destOffset; + if (destChannel == FXDIB_Alpha) { + if (IsAlphaMask()) { + if (!ConvertFormat(FXDIB_8bppMask)) { return FALSE; - } - ASSERT(pSrcBitmap->IsAlphaMask()); - if (!pSrcBitmap->IsAlphaMask()) { + } + destOffset = 0; + } else { + destOffset = 0; + if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyka : FXDIB_Argb)) { return FALSE; + } + if (GetFormat() == FXDIB_Argb) { + destOffset = 3; + } } - if (!IsAlphaMask() && !HasAlpha()) { - return LoadChannel(FXDIB_Alpha, pSrcBitmap, FXDIB_Alpha); + } else { + if (IsAlphaMask()) { + return FALSE; } - CFX_DIBitmap* pSrcClone = (CFX_DIBitmap*)pSrcBitmap; - if (pSrcBitmap->GetWidth() != m_Width || pSrcBitmap->GetHeight() != m_Height) { - pSrcClone = pSrcBitmap->StretchTo(m_Width, m_Height); - ASSERT(pSrcClone != NULL); - if (pSrcClone == NULL) { - return FALSE; + if (GetBPP() < 24) { + if (HasAlpha()) { + if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyka : FXDIB_Argb)) { + return FALSE; } + } else +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyk : FXDIB_Rgb)) { + return FALSE; + } +#else + if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyk : FXDIB_Rgb32)) { + return FALSE; + } +#endif } - if (IsAlphaMask()) { - if(!ConvertFormat(FXDIB_8bppMask)) { - if (pSrcClone != pSrcBitmap) { - delete pSrcClone; - } - return FALSE; - } - for (int row = 0; row < m_Height; row ++) { - uint8_t* dest_scan = m_pBuffer + m_Pitch * row; - uint8_t* src_scan = pSrcClone->m_pBuffer + pSrcClone->m_Pitch * row; - if (pSrcClone->GetBPP() == 1) { - for (int col = 0; col < m_Width; col ++) { - if (!((1 << (7 - col % 8)) & src_scan[col / 8])) { - dest_scan[col] = 0; - } - } - } else { - for (int col = 0; col < m_Width; col ++) { - *dest_scan = (*dest_scan) * src_scan[col] / 255; - dest_scan ++; - } - } + destOffset = g_ChannelOffset[destChannel]; + } + int Bpp = GetBPP() / 8; + if (Bpp == 1) { + FXSYS_memset(m_pBuffer, value, m_Height * m_Pitch); + return TRUE; + } + if (destChannel == FXDIB_Alpha && m_pAlphaMask) { + FXSYS_memset(m_pAlphaMask->GetBuffer(), value, + m_pAlphaMask->GetHeight() * m_pAlphaMask->GetPitch()); + return TRUE; + } + for (int row = 0; row < m_Height; row++) { + uint8_t* scan_line = m_pBuffer + row * m_Pitch + destOffset; + for (int col = 0; col < m_Width; col++) { + *scan_line = value; + scan_line += Bpp; + } + } + return TRUE; +} +FX_BOOL CFX_DIBitmap::MultiplyAlpha(const CFX_DIBSource* pSrcBitmap) { + if (m_pBuffer == NULL) { + return FALSE; + } + ASSERT(pSrcBitmap->IsAlphaMask()); + if (!pSrcBitmap->IsAlphaMask()) { + return FALSE; + } + if (!IsAlphaMask() && !HasAlpha()) { + return LoadChannel(FXDIB_Alpha, pSrcBitmap, FXDIB_Alpha); + } + CFX_DIBitmap* pSrcClone = (CFX_DIBitmap*)pSrcBitmap; + if (pSrcBitmap->GetWidth() != m_Width || + pSrcBitmap->GetHeight() != m_Height) { + pSrcClone = pSrcBitmap->StretchTo(m_Width, m_Height); + ASSERT(pSrcClone != NULL); + if (pSrcClone == NULL) { + return FALSE; + } + } + if (IsAlphaMask()) { + if (!ConvertFormat(FXDIB_8bppMask)) { + if (pSrcClone != pSrcBitmap) { + delete pSrcClone; + } + return FALSE; + } + for (int row = 0; row < m_Height; row++) { + uint8_t* dest_scan = m_pBuffer + m_Pitch * row; + uint8_t* src_scan = pSrcClone->m_pBuffer + pSrcClone->m_Pitch * row; + if (pSrcClone->GetBPP() == 1) { + for (int col = 0; col < m_Width; col++) { + if (!((1 << (7 - col % 8)) & src_scan[col / 8])) { + dest_scan[col] = 0; + } + } + } else { + for (int col = 0; col < m_Width; col++) { + *dest_scan = (*dest_scan) * src_scan[col] / 255; + dest_scan++; + } + } + } + } else { + if (GetFormat() == FXDIB_Argb) { + if (pSrcClone->GetBPP() == 1) { + if (pSrcClone != pSrcBitmap) { + delete pSrcClone; } + return FALSE; + } + for (int row = 0; row < m_Height; row++) { + uint8_t* dest_scan = m_pBuffer + m_Pitch * row + 3; + uint8_t* src_scan = pSrcClone->m_pBuffer + pSrcClone->m_Pitch * row; + for (int col = 0; col < m_Width; col++) { + *dest_scan = (*dest_scan) * src_scan[col] / 255; + dest_scan += 4; + } + } } else { - if(GetFormat() == FXDIB_Argb) { - if (pSrcClone->GetBPP() == 1) { - if (pSrcClone != pSrcBitmap) { - delete pSrcClone; - } - return FALSE; - } - for (int row = 0; row < m_Height; row ++) { - uint8_t* dest_scan = m_pBuffer + m_Pitch * row + 3; - uint8_t* src_scan = pSrcClone->m_pBuffer + pSrcClone->m_Pitch * row; - for (int col = 0; col < m_Width; col ++) { - *dest_scan = (*dest_scan) * src_scan[col] / 255; - dest_scan += 4; - } - } - } else { - m_pAlphaMask->MultiplyAlpha(pSrcClone); - } - } - if (pSrcClone != pSrcBitmap) { - delete pSrcClone; + m_pAlphaMask->MultiplyAlpha(pSrcClone); } - return TRUE; + } + if (pSrcClone != pSrcBitmap) { + delete pSrcClone; + } + return TRUE; } -FX_BOOL CFX_DIBitmap::GetGrayData(void* pIccTransform) -{ - if (m_pBuffer == NULL) { +FX_BOOL CFX_DIBitmap::GetGrayData(void* pIccTransform) { + if (m_pBuffer == NULL) { + return FALSE; + } + switch (GetFormat()) { + case FXDIB_1bppRgb: { + if (m_pPalette == NULL) { return FALSE; - } - switch (GetFormat()) { - case FXDIB_1bppRgb: { - if (m_pPalette == NULL) { - return FALSE; - } - uint8_t gray[2]; - for (int i = 0; i < 2; i ++) { - int r = (uint8_t)(m_pPalette[i] >> 16); - int g = (uint8_t)(m_pPalette[i] >> 8); - int b = (uint8_t)m_pPalette[i]; - gray[i] = (uint8_t)FXRGB2GRAY(r, g, b); - } - CFX_DIBitmap* pMask = new CFX_DIBitmap; - if (!pMask->Create(m_Width, m_Height, FXDIB_8bppMask)) { - delete pMask; - return FALSE; - } - FXSYS_memset(pMask->GetBuffer(), gray[0], pMask->GetPitch() * m_Height); - for (int row = 0; row < m_Height; row ++) { - uint8_t* src_pos = m_pBuffer + row * m_Pitch; - uint8_t* dest_pos = (uint8_t*)pMask->GetScanline(row); - for (int col = 0; col < m_Width; col ++) { - if (src_pos[col / 8] & (1 << (7 - col % 8))) { - *dest_pos = gray[1]; - } - dest_pos ++; - } - } - TakeOver(pMask); - delete pMask; - break; - } - case FXDIB_8bppRgb: { - if (m_pPalette == NULL) { - return FALSE; - } - uint8_t gray[256]; - for (int i = 0; i < 256; i ++) { - int r = (uint8_t)(m_pPalette[i] >> 16); - int g = (uint8_t)(m_pPalette[i] >> 8); - int b = (uint8_t)m_pPalette[i]; - gray[i] = (uint8_t)FXRGB2GRAY(r, g, b); - } - CFX_DIBitmap* pMask = new CFX_DIBitmap; - if (!pMask->Create(m_Width, m_Height, FXDIB_8bppMask)) { - delete pMask; - return FALSE; - } - for (int row = 0; row < m_Height; row ++) { - uint8_t* dest_pos = pMask->GetBuffer() + row * pMask->GetPitch(); - uint8_t* src_pos = m_pBuffer + row * m_Pitch; - for (int col = 0; col < m_Width; col ++) { - *dest_pos ++ = gray[*src_pos ++]; - } - } - TakeOver(pMask); - delete pMask; - break; - } - case FXDIB_Rgb: { - CFX_DIBitmap* pMask = new CFX_DIBitmap; - if (!pMask->Create(m_Width, m_Height, FXDIB_8bppMask)) { - delete pMask; - return FALSE; - } - for (int row = 0; row < m_Height; row ++) { - uint8_t* src_pos = m_pBuffer + row * m_Pitch; - uint8_t* dest_pos = pMask->GetBuffer() + row * pMask->GetPitch(); - for (int col = 0; col < m_Width; col ++) { - *dest_pos ++ = FXRGB2GRAY(src_pos[2], src_pos[1], *src_pos); - src_pos += 3; - } - } - TakeOver(pMask); - delete pMask; - break; - } - case FXDIB_Rgb32: { - CFX_DIBitmap* pMask = new CFX_DIBitmap; - if (!pMask->Create(m_Width, m_Height, FXDIB_8bppMask)) { - delete pMask; - return FALSE; - } - for (int row = 0; row < m_Height; row ++) { - uint8_t* src_pos = m_pBuffer + row * m_Pitch; - uint8_t* dest_pos = pMask->GetBuffer() + row * pMask->GetPitch(); - for (int col = 0; col < m_Width; col ++) { - *dest_pos ++ = FXRGB2GRAY(src_pos[2], src_pos[1], *src_pos); - src_pos += 4; - } - } - TakeOver(pMask); - delete pMask; - break; - } - default: - return FALSE; - } - return TRUE; + } + uint8_t gray[2]; + for (int i = 0; i < 2; i++) { + int r = (uint8_t)(m_pPalette[i] >> 16); + int g = (uint8_t)(m_pPalette[i] >> 8); + int b = (uint8_t)m_pPalette[i]; + gray[i] = (uint8_t)FXRGB2GRAY(r, g, b); + } + CFX_DIBitmap* pMask = new CFX_DIBitmap; + if (!pMask->Create(m_Width, m_Height, FXDIB_8bppMask)) { + delete pMask; + return FALSE; + } + FXSYS_memset(pMask->GetBuffer(), gray[0], pMask->GetPitch() * m_Height); + for (int row = 0; row < m_Height; row++) { + uint8_t* src_pos = m_pBuffer + row * m_Pitch; + uint8_t* dest_pos = (uint8_t*)pMask->GetScanline(row); + for (int col = 0; col < m_Width; col++) { + if (src_pos[col / 8] & (1 << (7 - col % 8))) { + *dest_pos = gray[1]; + } + dest_pos++; + } + } + TakeOver(pMask); + delete pMask; + break; + } + case FXDIB_8bppRgb: { + if (m_pPalette == NULL) { + return FALSE; + } + uint8_t gray[256]; + for (int i = 0; i < 256; i++) { + int r = (uint8_t)(m_pPalette[i] >> 16); + int g = (uint8_t)(m_pPalette[i] >> 8); + int b = (uint8_t)m_pPalette[i]; + gray[i] = (uint8_t)FXRGB2GRAY(r, g, b); + } + CFX_DIBitmap* pMask = new CFX_DIBitmap; + if (!pMask->Create(m_Width, m_Height, FXDIB_8bppMask)) { + delete pMask; + return FALSE; + } + for (int row = 0; row < m_Height; row++) { + uint8_t* dest_pos = pMask->GetBuffer() + row * pMask->GetPitch(); + uint8_t* src_pos = m_pBuffer + row * m_Pitch; + for (int col = 0; col < m_Width; col++) { + *dest_pos++ = gray[*src_pos++]; + } + } + TakeOver(pMask); + delete pMask; + break; + } + case FXDIB_Rgb: { + CFX_DIBitmap* pMask = new CFX_DIBitmap; + if (!pMask->Create(m_Width, m_Height, FXDIB_8bppMask)) { + delete pMask; + return FALSE; + } + for (int row = 0; row < m_Height; row++) { + uint8_t* src_pos = m_pBuffer + row * m_Pitch; + uint8_t* dest_pos = pMask->GetBuffer() + row * pMask->GetPitch(); + for (int col = 0; col < m_Width; col++) { + *dest_pos++ = FXRGB2GRAY(src_pos[2], src_pos[1], *src_pos); + src_pos += 3; + } + } + TakeOver(pMask); + delete pMask; + break; + } + case FXDIB_Rgb32: { + CFX_DIBitmap* pMask = new CFX_DIBitmap; + if (!pMask->Create(m_Width, m_Height, FXDIB_8bppMask)) { + delete pMask; + return FALSE; + } + for (int row = 0; row < m_Height; row++) { + uint8_t* src_pos = m_pBuffer + row * m_Pitch; + uint8_t* dest_pos = pMask->GetBuffer() + row * pMask->GetPitch(); + for (int col = 0; col < m_Width; col++) { + *dest_pos++ = FXRGB2GRAY(src_pos[2], src_pos[1], *src_pos); + src_pos += 4; + } + } + TakeOver(pMask); + delete pMask; + break; + } + default: + return FALSE; + } + return TRUE; } -FX_BOOL CFX_DIBitmap::MultiplyAlpha(int alpha) -{ - if (m_pBuffer == NULL) { +FX_BOOL CFX_DIBitmap::MultiplyAlpha(int alpha) { + if (m_pBuffer == NULL) { + return FALSE; + } + switch (GetFormat()) { + case FXDIB_1bppMask: + if (!ConvertFormat(FXDIB_8bppMask)) { return FALSE; - } - switch (GetFormat()) { - case FXDIB_1bppMask: - if (!ConvertFormat(FXDIB_8bppMask)) { - return FALSE; - } - MultiplyAlpha(alpha); - break; - case FXDIB_8bppMask: { - for (int row = 0; row < m_Height; row ++) { - uint8_t* scan_line = m_pBuffer + row * m_Pitch; - for (int col = 0; col < m_Width; col ++) { - scan_line[col] = scan_line[col] * alpha / 255; - } - } - break; - } - case FXDIB_Argb: { - for (int row = 0; row < m_Height; row ++) { - uint8_t* scan_line = m_pBuffer + row * m_Pitch + 3; - for (int col = 0; col < m_Width; col ++) { - *scan_line = (*scan_line) * alpha / 255; - scan_line += 4; - } - } - break; - } - default: - if (HasAlpha()) { - m_pAlphaMask->MultiplyAlpha(alpha); - } else if (IsCmykImage()) { - if (!ConvertFormat((FXDIB_Format)(GetFormat() | 0x0200))) { - return FALSE; - } - m_pAlphaMask->MultiplyAlpha(alpha); - } else { - if (!ConvertFormat(FXDIB_Argb)) { - return FALSE; - } - MultiplyAlpha(alpha); - } - break; - } - return TRUE; + } + MultiplyAlpha(alpha); + break; + case FXDIB_8bppMask: { + for (int row = 0; row < m_Height; row++) { + uint8_t* scan_line = m_pBuffer + row * m_Pitch; + for (int col = 0; col < m_Width; col++) { + scan_line[col] = scan_line[col] * alpha / 255; + } + } + break; + } + case FXDIB_Argb: { + for (int row = 0; row < m_Height; row++) { + uint8_t* scan_line = m_pBuffer + row * m_Pitch + 3; + for (int col = 0; col < m_Width; col++) { + *scan_line = (*scan_line) * alpha / 255; + scan_line += 4; + } + } + break; + } + default: + if (HasAlpha()) { + m_pAlphaMask->MultiplyAlpha(alpha); + } else if (IsCmykImage()) { + if (!ConvertFormat((FXDIB_Format)(GetFormat() | 0x0200))) { + return FALSE; + } + m_pAlphaMask->MultiplyAlpha(alpha); + } else { + if (!ConvertFormat(FXDIB_Argb)) { + return FALSE; + } + MultiplyAlpha(alpha); + } + break; + } + return TRUE; } -FX_DWORD CFX_DIBitmap::GetPixel(int x, int y) const -{ - if (m_pBuffer == NULL) { - return 0; - } - uint8_t* pos = m_pBuffer + y * m_Pitch + x * GetBPP() / 8; - switch (GetFormat()) { - case FXDIB_1bppMask: { - if ((*pos) & (1 << (7 - x % 8))) { - return 0xff000000; - } - return 0; - } - case FXDIB_1bppRgb: { - if ((*pos) & (1 << (7 - x % 8))) { - return m_pPalette ? m_pPalette[1] : 0xffffffff; - } - return m_pPalette ? m_pPalette[0] : 0xff000000; - } - case FXDIB_8bppMask: - return (*pos) << 24; - case FXDIB_8bppRgb: - return m_pPalette ? m_pPalette[*pos] : (0xff000000 | ((*pos) * 0x10101)); - case FXDIB_Rgb: - case FXDIB_Rgba: - case FXDIB_Rgb32: - return FXARGB_GETDIB(pos) | 0xff000000; - case FXDIB_Argb: - return FXARGB_GETDIB(pos); - default: - break; - } +FX_DWORD CFX_DIBitmap::GetPixel(int x, int y) const { + if (m_pBuffer == NULL) { return 0; + } + uint8_t* pos = m_pBuffer + y * m_Pitch + x * GetBPP() / 8; + switch (GetFormat()) { + case FXDIB_1bppMask: { + if ((*pos) & (1 << (7 - x % 8))) { + return 0xff000000; + } + return 0; + } + case FXDIB_1bppRgb: { + if ((*pos) & (1 << (7 - x % 8))) { + return m_pPalette ? m_pPalette[1] : 0xffffffff; + } + return m_pPalette ? m_pPalette[0] : 0xff000000; + } + case FXDIB_8bppMask: + return (*pos) << 24; + case FXDIB_8bppRgb: + return m_pPalette ? m_pPalette[*pos] : (0xff000000 | ((*pos) * 0x10101)); + case FXDIB_Rgb: + case FXDIB_Rgba: + case FXDIB_Rgb32: + return FXARGB_GETDIB(pos) | 0xff000000; + case FXDIB_Argb: + return FXARGB_GETDIB(pos); + default: + break; + } + return 0; } -void CFX_DIBitmap::SetPixel(int x, int y, FX_DWORD color) -{ - if (m_pBuffer == NULL) { - return; - } - if (x < 0 || x >= m_Width || y < 0 || y >= m_Height) { - return; - } - uint8_t* pos = m_pBuffer + y * m_Pitch + x * GetBPP() / 8; - switch (GetFormat()) { - case FXDIB_1bppMask: - if (color >> 24) { - *pos |= 1 << (7 - x % 8); - } else { - *pos &= ~(1 << (7 - x % 8)); - } - break; - case FXDIB_1bppRgb: - if (m_pPalette) { - if (color == m_pPalette[1]) { - *pos |= 1 << (7 - x % 8); - } else { - *pos &= ~(1 << (7 - x % 8)); - } - } else { - if (color == 0xffffffff) { - *pos |= 1 << (7 - x % 8); - } else { - *pos &= ~(1 << (7 - x % 8)); - } - } - break; - case FXDIB_8bppMask: - *pos = (uint8_t)(color >> 24); - break; - case FXDIB_8bppRgb: { - if (m_pPalette) { - for (int i = 0; i < 256; i ++) { - if (m_pPalette[i] == color) { - *pos = (uint8_t)i; - return; - } - } - *pos = 0; - } else { - *pos = FXRGB2GRAY(FXARGB_R(color), FXARGB_G(color), FXARGB_B(color)); - } - break; - } - case FXDIB_Rgb: - case FXDIB_Rgb32: { - int alpha = FXARGB_A(color); - pos[0] = (FXARGB_B(color) * alpha + pos[0] * (255 - alpha)) / 255; - pos[1] = (FXARGB_G(color) * alpha + pos[1] * (255 - alpha)) / 255; - pos[2] = (FXARGB_R(color) * alpha + pos[2] * (255 - alpha)) / 255; - break; - } - case FXDIB_Rgba: { - pos[0] = FXARGB_B(color); - pos[1] = FXARGB_G(color); - pos[2] = FXARGB_R(color); - break; - } - case FXDIB_Argb: - FXARGB_SETDIB(pos, color); - break; - default: - break; - } -} -void CFX_DIBitmap::DownSampleScanline(int line, uint8_t* dest_scan, int dest_bpp, - int dest_width, FX_BOOL bFlipX, int clip_left, int clip_width) const -{ - if (m_pBuffer == NULL) { - return; - } - int src_Bpp = m_bpp / 8; - uint8_t* scanline = m_pBuffer + line * m_Pitch; - if (src_Bpp == 0) { - for (int i = 0; i < clip_width; i ++) { - FX_DWORD dest_x = clip_left + i; - FX_DWORD src_x = dest_x * m_Width / dest_width; - if (bFlipX) { - src_x = m_Width - src_x - 1; - } - src_x %= m_Width; - dest_scan[i] = (scanline[src_x / 8] & (1 << (7 - src_x % 8))) ? 255 : 0; - } - } else if (src_Bpp == 1) { - for (int i = 0; i < clip_width; i ++) { - FX_DWORD dest_x = clip_left + i; - FX_DWORD src_x = dest_x * m_Width / dest_width; - if (bFlipX) { - src_x = m_Width - src_x - 1; - } - src_x %= m_Width; - int dest_pos = i; - if (m_pPalette) { - if (!IsCmykImage()) { - dest_pos *= 3; - FX_ARGB argb = m_pPalette[scanline[src_x]]; - dest_scan[dest_pos] = FXARGB_B(argb); - dest_scan[dest_pos + 1] = FXARGB_G(argb); - dest_scan[dest_pos + 2] = FXARGB_R(argb); - } else { - dest_pos *= 4; - FX_CMYK cmyk = m_pPalette[scanline[src_x]]; - dest_scan[dest_pos] = FXSYS_GetCValue(cmyk); - dest_scan[dest_pos + 1] = FXSYS_GetMValue(cmyk); - dest_scan[dest_pos + 2] = FXSYS_GetYValue(cmyk); - dest_scan[dest_pos + 3] = FXSYS_GetKValue(cmyk); - } - } else { - dest_scan[dest_pos] = scanline[src_x]; - } - } - } else { - for (int i = 0; i < clip_width; i ++) { - FX_DWORD dest_x = clip_left + i; - FX_DWORD src_x = bFlipX ? (m_Width - dest_x * m_Width / dest_width - 1) * src_Bpp : (dest_x * m_Width / dest_width) * src_Bpp; - src_x %= m_Width * src_Bpp; - int dest_pos = i * src_Bpp; - for (int b = 0; b < src_Bpp; b ++) { - dest_scan[dest_pos + b] = scanline[src_x + b]; - } +void CFX_DIBitmap::SetPixel(int x, int y, FX_DWORD color) { + if (m_pBuffer == NULL) { + return; + } + if (x < 0 || x >= m_Width || y < 0 || y >= m_Height) { + return; + } + uint8_t* pos = m_pBuffer + y * m_Pitch + x * GetBPP() / 8; + switch (GetFormat()) { + case FXDIB_1bppMask: + if (color >> 24) { + *pos |= 1 << (7 - x % 8); + } else { + *pos &= ~(1 << (7 - x % 8)); + } + break; + case FXDIB_1bppRgb: + if (m_pPalette) { + if (color == m_pPalette[1]) { + *pos |= 1 << (7 - x % 8); + } else { + *pos &= ~(1 << (7 - x % 8)); } - } + } else { + if (color == 0xffffffff) { + *pos |= 1 << (7 - x % 8); + } else { + *pos &= ~(1 << (7 - x % 8)); + } + } + break; + case FXDIB_8bppMask: + *pos = (uint8_t)(color >> 24); + break; + case FXDIB_8bppRgb: { + if (m_pPalette) { + for (int i = 0; i < 256; i++) { + if (m_pPalette[i] == color) { + *pos = (uint8_t)i; + return; + } + } + *pos = 0; + } else { + *pos = FXRGB2GRAY(FXARGB_R(color), FXARGB_G(color), FXARGB_B(color)); + } + break; + } + case FXDIB_Rgb: + case FXDIB_Rgb32: { + int alpha = FXARGB_A(color); + pos[0] = (FXARGB_B(color) * alpha + pos[0] * (255 - alpha)) / 255; + pos[1] = (FXARGB_G(color) * alpha + pos[1] * (255 - alpha)) / 255; + pos[2] = (FXARGB_R(color) * alpha + pos[2] * (255 - alpha)) / 255; + break; + } + case FXDIB_Rgba: { + pos[0] = FXARGB_B(color); + pos[1] = FXARGB_G(color); + pos[2] = FXARGB_R(color); + break; + } + case FXDIB_Argb: + FXARGB_SETDIB(pos, color); + break; + default: + break; + } } -FX_BOOL CFX_DIBitmap::ConvertColorScale(FX_DWORD forecolor, FX_DWORD backcolor) -{ - ASSERT(!IsAlphaMask()); - if (m_pBuffer == NULL || IsAlphaMask()) { - return FALSE; - } - int fc, fm, fy, fk, bc, bm, by, bk; - int fr, fg, fb, br, bg, bb; - FX_BOOL isCmykImage = IsCmykImage(); +void CFX_DIBitmap::DownSampleScanline(int line, + uint8_t* dest_scan, + int dest_bpp, + int dest_width, + FX_BOOL bFlipX, + int clip_left, + int clip_width) const { + if (m_pBuffer == NULL) { + return; + } + int src_Bpp = m_bpp / 8; + uint8_t* scanline = m_pBuffer + line * m_Pitch; + if (src_Bpp == 0) { + for (int i = 0; i < clip_width; i++) { + FX_DWORD dest_x = clip_left + i; + FX_DWORD src_x = dest_x * m_Width / dest_width; + if (bFlipX) { + src_x = m_Width - src_x - 1; + } + src_x %= m_Width; + dest_scan[i] = (scanline[src_x / 8] & (1 << (7 - src_x % 8))) ? 255 : 0; + } + } else if (src_Bpp == 1) { + for (int i = 0; i < clip_width; i++) { + FX_DWORD dest_x = clip_left + i; + FX_DWORD src_x = dest_x * m_Width / dest_width; + if (bFlipX) { + src_x = m_Width - src_x - 1; + } + src_x %= m_Width; + int dest_pos = i; + if (m_pPalette) { + if (!IsCmykImage()) { + dest_pos *= 3; + FX_ARGB argb = m_pPalette[scanline[src_x]]; + dest_scan[dest_pos] = FXARGB_B(argb); + dest_scan[dest_pos + 1] = FXARGB_G(argb); + dest_scan[dest_pos + 2] = FXARGB_R(argb); + } else { + dest_pos *= 4; + FX_CMYK cmyk = m_pPalette[scanline[src_x]]; + dest_scan[dest_pos] = FXSYS_GetCValue(cmyk); + dest_scan[dest_pos + 1] = FXSYS_GetMValue(cmyk); + dest_scan[dest_pos + 2] = FXSYS_GetYValue(cmyk); + dest_scan[dest_pos + 3] = FXSYS_GetKValue(cmyk); + } + } else { + dest_scan[dest_pos] = scanline[src_x]; + } + } + } else { + for (int i = 0; i < clip_width; i++) { + FX_DWORD dest_x = clip_left + i; + FX_DWORD src_x = + bFlipX ? (m_Width - dest_x * m_Width / dest_width - 1) * src_Bpp + : (dest_x * m_Width / dest_width) * src_Bpp; + src_x %= m_Width * src_Bpp; + int dest_pos = i * src_Bpp; + for (int b = 0; b < src_Bpp; b++) { + dest_scan[dest_pos + b] = scanline[src_x + b]; + } + } + } +} +FX_BOOL CFX_DIBitmap::ConvertColorScale(FX_DWORD forecolor, + FX_DWORD backcolor) { + ASSERT(!IsAlphaMask()); + if (m_pBuffer == NULL || IsAlphaMask()) { + return FALSE; + } + int fc, fm, fy, fk, bc, bm, by, bk; + int fr, fg, fb, br, bg, bb; + FX_BOOL isCmykImage = IsCmykImage(); + if (isCmykImage) { + fc = FXSYS_GetCValue(forecolor); + fm = FXSYS_GetMValue(forecolor); + fy = FXSYS_GetYValue(forecolor); + fk = FXSYS_GetKValue(forecolor); + bc = FXSYS_GetCValue(backcolor); + bm = FXSYS_GetMValue(backcolor); + by = FXSYS_GetYValue(backcolor); + bk = FXSYS_GetKValue(backcolor); + } else { + fr = FXSYS_GetRValue(forecolor); + fg = FXSYS_GetGValue(forecolor); + fb = FXSYS_GetBValue(forecolor); + br = FXSYS_GetRValue(backcolor); + bg = FXSYS_GetGValue(backcolor); + bb = FXSYS_GetBValue(backcolor); + } + if (m_bpp <= 8) { if (isCmykImage) { - fc = FXSYS_GetCValue(forecolor); - fm = FXSYS_GetMValue(forecolor); - fy = FXSYS_GetYValue(forecolor); - fk = FXSYS_GetKValue(forecolor); - bc = FXSYS_GetCValue(backcolor); - bm = FXSYS_GetMValue(backcolor); - by = FXSYS_GetYValue(backcolor); - bk = FXSYS_GetKValue(backcolor); - } else { - fr = FXSYS_GetRValue(forecolor); - fg = FXSYS_GetGValue(forecolor); - fb = FXSYS_GetBValue(forecolor); - br = FXSYS_GetRValue(backcolor); - bg = FXSYS_GetGValue(backcolor); - bb = FXSYS_GetBValue(backcolor); - } - if (m_bpp <= 8) { - if (isCmykImage) { - if (forecolor == 0xff && backcolor == 0 && m_pPalette == NULL) { - return TRUE; - } - } else if (forecolor == 0 && backcolor == 0xffffff && m_pPalette == NULL) { - return TRUE; - } - if (m_pPalette == NULL) { - BuildPalette(); - } - int size = 1 << m_bpp; - if (isCmykImage) { - for (int i = 0; i < size; i ++) { - uint8_t b, g, r; - AdobeCMYK_to_sRGB1(FXSYS_GetCValue(m_pPalette[i]), FXSYS_GetMValue(m_pPalette[i]), FXSYS_GetYValue(m_pPalette[i]), FXSYS_GetKValue(m_pPalette[i]), - r, g, b); - int gray = 255 - FXRGB2GRAY(r, g, b); - m_pPalette[i] = CmykEncode(bc + (fc - bc) * gray / 255, bm + (fm - bm) * gray / 255, - by + (fy - by) * gray / 255, bk + (fk - bk) * gray / 255); - } - } else - for (int i = 0; i < size; i ++) { - int gray = FXRGB2GRAY(FXARGB_R(m_pPalette[i]), FXARGB_G(m_pPalette[i]), FXARGB_B(m_pPalette[i])); - m_pPalette[i] = FXARGB_MAKE(0xff, br + (fr - br) * gray / 255, bg + (fg - bg) * gray / 255, - bb + (fb - bb) * gray / 255); - } + if (forecolor == 0xff && backcolor == 0 && m_pPalette == NULL) { return TRUE; + } + } else if (forecolor == 0 && backcolor == 0xffffff && m_pPalette == NULL) { + return TRUE; } - if (isCmykImage) { - if (forecolor == 0xff && backcolor == 0x00) { - for (int row = 0; row < m_Height; row ++) { - uint8_t* scanline = m_pBuffer + row * m_Pitch; - for (int col = 0; col < m_Width; col ++) { - uint8_t b, g, r; - AdobeCMYK_to_sRGB1(scanline[0], scanline[1], scanline[2], scanline[3], - r, g, b); - *scanline ++ = 0; - *scanline ++ = 0; - *scanline ++ = 0; - *scanline ++ = 255 - FXRGB2GRAY(r, g, b); - } - } - return TRUE; - } - } else if (forecolor == 0 && backcolor == 0xffffff) { - for (int row = 0; row < m_Height; row ++) { - uint8_t* scanline = m_pBuffer + row * m_Pitch; - int gap = m_bpp / 8 - 2; - for (int col = 0; col < m_Width; col ++) { - int gray = FXRGB2GRAY(scanline[2], scanline[1], scanline[0]); - *scanline ++ = gray; - *scanline ++ = gray; - *scanline = gray; - scanline += gap; - } - } - return TRUE; + if (m_pPalette == NULL) { + BuildPalette(); } + int size = 1 << m_bpp; if (isCmykImage) { - for (int row = 0; row < m_Height; row ++) { - uint8_t* scanline = m_pBuffer + row * m_Pitch; - for (int col = 0; col < m_Width; col ++) { - uint8_t b, g, r; - AdobeCMYK_to_sRGB1(scanline[0], scanline[1], scanline[2], scanline[3], - r, g, b); - int gray = 255 - FXRGB2GRAY(r, g, b); - *scanline ++ = bc + (fc - bc) * gray / 255; - *scanline ++ = bm + (fm - bm) * gray / 255; - *scanline ++ = by + (fy - by) * gray / 255; - *scanline ++ = bk + (fk - bk) * gray / 255; - } - } - } else { - for (int row = 0; row < m_Height; row ++) { - uint8_t* scanline = m_pBuffer + row * m_Pitch; - int gap = m_bpp / 8 - 2; - for (int col = 0; col < m_Width; col ++) { - int gray = FXRGB2GRAY(scanline[2], scanline[1], scanline[0]); - *scanline ++ = bb + (fb - bb) * gray / 255; - *scanline ++ = bg + (fg - bg) * gray / 255; - *scanline = br + (fr - br) * gray / 255; - scanline += gap; - } - } - } + for (int i = 0; i < size; i++) { + uint8_t b, g, r; + AdobeCMYK_to_sRGB1(FXSYS_GetCValue(m_pPalette[i]), + FXSYS_GetMValue(m_pPalette[i]), + FXSYS_GetYValue(m_pPalette[i]), + FXSYS_GetKValue(m_pPalette[i]), r, g, b); + int gray = 255 - FXRGB2GRAY(r, g, b); + m_pPalette[i] = CmykEncode( + bc + (fc - bc) * gray / 255, bm + (fm - bm) * gray / 255, + by + (fy - by) * gray / 255, bk + (fk - bk) * gray / 255); + } + } else + for (int i = 0; i < size; i++) { + int gray = FXRGB2GRAY(FXARGB_R(m_pPalette[i]), FXARGB_G(m_pPalette[i]), + FXARGB_B(m_pPalette[i])); + m_pPalette[i] = FXARGB_MAKE(0xff, br + (fr - br) * gray / 255, + bg + (fg - bg) * gray / 255, + bb + (fb - bb) * gray / 255); + } return TRUE; -} -FX_BOOL CFX_DIBitmap::DitherFS(const FX_DWORD* pPalette, int pal_size, const FX_RECT* pRect) -{ - if (m_pBuffer == NULL) { - return FALSE; - } - if (m_bpp != 8 && m_pPalette != NULL && m_AlphaFlag != 0) { - return FALSE; - } - if (m_Width < 4 && m_Height < 4) { - return FALSE; - } - FX_RECT rect(0, 0, m_Width, m_Height); - if (pRect) { - rect.Intersect(*pRect); - } - uint8_t translate[256]; - for (int i = 0; i < 256; i ++) { - int err2 = 65536; - for (int j = 0; j < pal_size; j ++) { - uint8_t entry = (uint8_t)pPalette[j]; - int err = (int)entry - i; - if (err * err < err2) { - err2 = err * err; - translate[i] = entry; - } - } - } - for (int row = rect.top; row < rect.bottom; row ++) { - uint8_t* scan = m_pBuffer + row * m_Pitch; - uint8_t* next_scan = m_pBuffer + (row + 1) * m_Pitch; - for (int col = rect.left; col < rect.right; col ++) { - int src_pixel = scan[col]; - int dest_pixel = translate[src_pixel]; - scan[col] = (uint8_t)dest_pixel; - int error = -dest_pixel + src_pixel; - if (col < rect.right - 1) { - int src = scan[col + 1]; - src += error * 7 / 16; - if (src > 255) { - scan[col + 1] = 255; - } else if (src < 0) { - scan[col + 1] = 0; - } else { - scan[col + 1] = src; - } - } - if (col < rect.right - 1 && row < rect.bottom - 1) { - int src = next_scan[col + 1]; - src += error * 1 / 16; - if (src > 255) { - next_scan[col + 1] = 255; - } else if (src < 0) { - next_scan[col + 1] = 0; - } else { - next_scan[col + 1] = src; - } - } - if (row < rect.bottom - 1) { - int src = next_scan[col]; - src += error * 5 / 16; - if (src > 255) { - next_scan[col] = 255; - } else if (src < 0) { - next_scan[col] = 0; - } else { - next_scan[col] = src; - } - } - if (col > rect.left && row < rect.bottom - 1) { - int src = next_scan[col - 1]; - src += error * 3 / 16; - if (src > 255) { - next_scan[col - 1] = 255; - } else if (src < 0) { - next_scan[col - 1] = 0; - } else { - next_scan[col - 1] = src; - } - } - } + } + if (isCmykImage) { + if (forecolor == 0xff && backcolor == 0x00) { + for (int row = 0; row < m_Height; row++) { + uint8_t* scanline = m_pBuffer + row * m_Pitch; + for (int col = 0; col < m_Width; col++) { + uint8_t b, g, r; + AdobeCMYK_to_sRGB1(scanline[0], scanline[1], scanline[2], scanline[3], + r, g, b); + *scanline++ = 0; + *scanline++ = 0; + *scanline++ = 0; + *scanline++ = 255 - FXRGB2GRAY(r, g, b); + } + } + return TRUE; + } + } else if (forecolor == 0 && backcolor == 0xffffff) { + for (int row = 0; row < m_Height; row++) { + uint8_t* scanline = m_pBuffer + row * m_Pitch; + int gap = m_bpp / 8 - 2; + for (int col = 0; col < m_Width; col++) { + int gray = FXRGB2GRAY(scanline[2], scanline[1], scanline[0]); + *scanline++ = gray; + *scanline++ = gray; + *scanline = gray; + scanline += gap; + } } return TRUE; + } + if (isCmykImage) { + for (int row = 0; row < m_Height; row++) { + uint8_t* scanline = m_pBuffer + row * m_Pitch; + for (int col = 0; col < m_Width; col++) { + uint8_t b, g, r; + AdobeCMYK_to_sRGB1(scanline[0], scanline[1], scanline[2], scanline[3], + r, g, b); + int gray = 255 - FXRGB2GRAY(r, g, b); + *scanline++ = bc + (fc - bc) * gray / 255; + *scanline++ = bm + (fm - bm) * gray / 255; + *scanline++ = by + (fy - by) * gray / 255; + *scanline++ = bk + (fk - bk) * gray / 255; + } + } + } else { + for (int row = 0; row < m_Height; row++) { + uint8_t* scanline = m_pBuffer + row * m_Pitch; + int gap = m_bpp / 8 - 2; + for (int col = 0; col < m_Width; col++) { + int gray = FXRGB2GRAY(scanline[2], scanline[1], scanline[0]); + *scanline++ = bb + (fb - bb) * gray / 255; + *scanline++ = bg + (fg - bg) * gray / 255; + *scanline = br + (fr - br) * gray / 255; + scanline += gap; + } + } + } + return TRUE; } -CFX_DIBitmap* CFX_DIBSource::FlipImage(FX_BOOL bXFlip, FX_BOOL bYFlip) const -{ - CFX_DIBitmap* pFlipped = new CFX_DIBitmap; - if (!pFlipped->Create(m_Width, m_Height, GetFormat())) { - delete pFlipped; - return NULL; - } - pFlipped->CopyPalette(m_pPalette); - uint8_t* pDestBuffer = pFlipped->GetBuffer(); - int Bpp = m_bpp / 8; - for (int row = 0; row < m_Height; row ++) { - const uint8_t* src_scan = GetScanline(row); - uint8_t* dest_scan = pDestBuffer + m_Pitch * (bYFlip ? (m_Height - row - 1) : row); - if (!bXFlip) { - FXSYS_memcpy(dest_scan, src_scan, m_Pitch); - continue; - } - if (m_bpp == 1) { - FXSYS_memset(dest_scan, 0, m_Pitch); - for (int col = 0; col < m_Width; col ++) - if (src_scan[col / 8] & (1 << (7 - col % 8))) { - int dest_col = m_Width - col - 1; - dest_scan[dest_col / 8] |= (1 << (7 - dest_col % 8)); - } +FX_BOOL CFX_DIBitmap::DitherFS(const FX_DWORD* pPalette, + int pal_size, + const FX_RECT* pRect) { + if (m_pBuffer == NULL) { + return FALSE; + } + if (m_bpp != 8 && m_pPalette != NULL && m_AlphaFlag != 0) { + return FALSE; + } + if (m_Width < 4 && m_Height < 4) { + return FALSE; + } + FX_RECT rect(0, 0, m_Width, m_Height); + if (pRect) { + rect.Intersect(*pRect); + } + uint8_t translate[256]; + for (int i = 0; i < 256; i++) { + int err2 = 65536; + for (int j = 0; j < pal_size; j++) { + uint8_t entry = (uint8_t)pPalette[j]; + int err = (int)entry - i; + if (err * err < err2) { + err2 = err * err; + translate[i] = entry; + } + } + } + for (int row = rect.top; row < rect.bottom; row++) { + uint8_t* scan = m_pBuffer + row * m_Pitch; + uint8_t* next_scan = m_pBuffer + (row + 1) * m_Pitch; + for (int col = rect.left; col < rect.right; col++) { + int src_pixel = scan[col]; + int dest_pixel = translate[src_pixel]; + scan[col] = (uint8_t)dest_pixel; + int error = -dest_pixel + src_pixel; + if (col < rect.right - 1) { + int src = scan[col + 1]; + src += error * 7 / 16; + if (src > 255) { + scan[col + 1] = 255; + } else if (src < 0) { + scan[col + 1] = 0; } else { - dest_scan += (m_Width - 1) * Bpp; - if (Bpp == 1) { - for (int col = 0; col < m_Width; col ++) { - *dest_scan = *src_scan; - dest_scan --; - src_scan ++; - } - } else if (Bpp == 3) { - for (int col = 0; col < m_Width; col ++) { - dest_scan[0] = src_scan[0]; - dest_scan[1] = src_scan[1]; - dest_scan[2] = src_scan[2]; - dest_scan -= 3; - src_scan += 3; - } - } else { - ASSERT(Bpp == 4); - for (int col = 0; col < m_Width; col ++) { - *(FX_DWORD*)dest_scan = *(FX_DWORD*)src_scan; - dest_scan -= 4; - src_scan += 4; - } - } - } - } - if (m_pAlphaMask) { - pDestBuffer = pFlipped->m_pAlphaMask->GetBuffer(); - FX_DWORD dest_pitch = pFlipped->m_pAlphaMask->GetPitch(); - for (int row = 0; row < m_Height; row ++) { - const uint8_t* src_scan = m_pAlphaMask->GetScanline(row); - uint8_t* dest_scan = pDestBuffer + dest_pitch * (bYFlip ? (m_Height - row - 1) : row); - if (!bXFlip) { - FXSYS_memcpy(dest_scan, src_scan, dest_pitch); - continue; - } - dest_scan += (m_Width - 1); - for (int col = 0; col < m_Width; col ++) { - *dest_scan = *src_scan; - dest_scan --; - src_scan ++; - } + scan[col + 1] = src; + } + } + if (col < rect.right - 1 && row < rect.bottom - 1) { + int src = next_scan[col + 1]; + src += error * 1 / 16; + if (src > 255) { + next_scan[col + 1] = 255; + } else if (src < 0) { + next_scan[col + 1] = 0; + } else { + next_scan[col + 1] = src; + } + } + if (row < rect.bottom - 1) { + int src = next_scan[col]; + src += error * 5 / 16; + if (src > 255) { + next_scan[col] = 255; + } else if (src < 0) { + next_scan[col] = 0; + } else { + next_scan[col] = src; + } + } + if (col > rect.left && row < rect.bottom - 1) { + int src = next_scan[col - 1]; + src += error * 3 / 16; + if (src > 255) { + next_scan[col - 1] = 255; + } else if (src < 0) { + next_scan[col - 1] = 0; + } else { + next_scan[col - 1] = src; } + } } - return pFlipped; + } + return TRUE; } -CFX_DIBExtractor::CFX_DIBExtractor(const CFX_DIBSource* pSrc) -{ - m_pBitmap = NULL; - if (pSrc->GetBuffer() == NULL) { - m_pBitmap = pSrc->Clone(); - } else { - m_pBitmap = new CFX_DIBitmap; - if (!m_pBitmap->Create(pSrc->GetWidth(), pSrc->GetHeight(), pSrc->GetFormat(), pSrc->GetBuffer())) { - delete m_pBitmap; - m_pBitmap = NULL; - return; +CFX_DIBitmap* CFX_DIBSource::FlipImage(FX_BOOL bXFlip, FX_BOOL bYFlip) const { + CFX_DIBitmap* pFlipped = new CFX_DIBitmap; + if (!pFlipped->Create(m_Width, m_Height, GetFormat())) { + delete pFlipped; + return NULL; + } + pFlipped->CopyPalette(m_pPalette); + uint8_t* pDestBuffer = pFlipped->GetBuffer(); + int Bpp = m_bpp / 8; + for (int row = 0; row < m_Height; row++) { + const uint8_t* src_scan = GetScanline(row); + uint8_t* dest_scan = + pDestBuffer + m_Pitch * (bYFlip ? (m_Height - row - 1) : row); + if (!bXFlip) { + FXSYS_memcpy(dest_scan, src_scan, m_Pitch); + continue; + } + if (m_bpp == 1) { + FXSYS_memset(dest_scan, 0, m_Pitch); + for (int col = 0; col < m_Width; col++) + if (src_scan[col / 8] & (1 << (7 - col % 8))) { + int dest_col = m_Width - col - 1; + dest_scan[dest_col / 8] |= (1 << (7 - dest_col % 8)); } - m_pBitmap->CopyPalette(pSrc->GetPalette()); - m_pBitmap->CopyAlphaMask(pSrc->m_pAlphaMask); - } + } else { + dest_scan += (m_Width - 1) * Bpp; + if (Bpp == 1) { + for (int col = 0; col < m_Width; col++) { + *dest_scan = *src_scan; + dest_scan--; + src_scan++; + } + } else if (Bpp == 3) { + for (int col = 0; col < m_Width; col++) { + dest_scan[0] = src_scan[0]; + dest_scan[1] = src_scan[1]; + dest_scan[2] = src_scan[2]; + dest_scan -= 3; + src_scan += 3; + } + } else { + ASSERT(Bpp == 4); + for (int col = 0; col < m_Width; col++) { + *(FX_DWORD*)dest_scan = *(FX_DWORD*)src_scan; + dest_scan -= 4; + src_scan += 4; + } + } + } + } + if (m_pAlphaMask) { + pDestBuffer = pFlipped->m_pAlphaMask->GetBuffer(); + FX_DWORD dest_pitch = pFlipped->m_pAlphaMask->GetPitch(); + for (int row = 0; row < m_Height; row++) { + const uint8_t* src_scan = m_pAlphaMask->GetScanline(row); + uint8_t* dest_scan = + pDestBuffer + dest_pitch * (bYFlip ? (m_Height - row - 1) : row); + if (!bXFlip) { + FXSYS_memcpy(dest_scan, src_scan, dest_pitch); + continue; + } + dest_scan += (m_Width - 1); + for (int col = 0; col < m_Width; col++) { + *dest_scan = *src_scan; + dest_scan--; + src_scan++; + } + } + } + return pFlipped; } -CFX_DIBExtractor::~CFX_DIBExtractor() -{ - delete m_pBitmap; +CFX_DIBExtractor::CFX_DIBExtractor(const CFX_DIBSource* pSrc) { + m_pBitmap = NULL; + if (pSrc->GetBuffer() == NULL) { + m_pBitmap = pSrc->Clone(); + } else { + m_pBitmap = new CFX_DIBitmap; + if (!m_pBitmap->Create(pSrc->GetWidth(), pSrc->GetHeight(), + pSrc->GetFormat(), pSrc->GetBuffer())) { + delete m_pBitmap; + m_pBitmap = NULL; + return; + } + m_pBitmap->CopyPalette(pSrc->GetPalette()); + m_pBitmap->CopyAlphaMask(pSrc->m_pAlphaMask); + } } -CFX_FilteredDIB::CFX_FilteredDIB() -{ - m_pScanline = NULL; - m_pSrc = NULL; +CFX_DIBExtractor::~CFX_DIBExtractor() { + delete m_pBitmap; } -CFX_FilteredDIB::~CFX_FilteredDIB() -{ - if (m_bAutoDropSrc) { - delete m_pSrc; - } - if (m_pScanline) { - FX_Free(m_pScanline); - } +CFX_FilteredDIB::CFX_FilteredDIB() { + m_pScanline = NULL; + m_pSrc = NULL; } -void CFX_FilteredDIB::LoadSrc(const CFX_DIBSource* pSrc, FX_BOOL bAutoDropSrc) -{ - m_pSrc = pSrc; - m_bAutoDropSrc = bAutoDropSrc; - m_Width = pSrc->GetWidth(); - m_Height = pSrc->GetHeight(); - FXDIB_Format format = GetDestFormat(); - m_bpp = (uint8_t)format; - m_AlphaFlag = (uint8_t)(format >> 8); - m_Pitch = (m_Width * (format & 0xff) + 31) / 32 * 4; - m_pPalette = GetDestPalette(); - m_pScanline = FX_Alloc(uint8_t, m_Pitch); +CFX_FilteredDIB::~CFX_FilteredDIB() { + if (m_bAutoDropSrc) { + delete m_pSrc; + } + if (m_pScanline) { + FX_Free(m_pScanline); + } } -const uint8_t* CFX_FilteredDIB::GetScanline(int line) const -{ - TranslateScanline(m_pScanline, m_pSrc->GetScanline(line)); - return m_pScanline; +void CFX_FilteredDIB::LoadSrc(const CFX_DIBSource* pSrc, FX_BOOL bAutoDropSrc) { + m_pSrc = pSrc; + m_bAutoDropSrc = bAutoDropSrc; + m_Width = pSrc->GetWidth(); + m_Height = pSrc->GetHeight(); + FXDIB_Format format = GetDestFormat(); + m_bpp = (uint8_t)format; + m_AlphaFlag = (uint8_t)(format >> 8); + m_Pitch = (m_Width * (format & 0xff) + 31) / 32 * 4; + m_pPalette = GetDestPalette(); + m_pScanline = FX_Alloc(uint8_t, m_Pitch); } -void CFX_FilteredDIB::DownSampleScanline(int line, uint8_t* dest_scan, int dest_bpp, - int dest_width, FX_BOOL bFlipX, int clip_left, int clip_width) const -{ - m_pSrc->DownSampleScanline(line, dest_scan, dest_bpp, dest_width, bFlipX, clip_left, clip_width); - TranslateDownSamples(dest_scan, dest_scan, clip_width, dest_bpp); +const uint8_t* CFX_FilteredDIB::GetScanline(int line) const { + TranslateScanline(m_pScanline, m_pSrc->GetScanline(line)); + return m_pScanline; } -CFX_ImageRenderer::CFX_ImageRenderer() -{ - m_Status = 0; - m_pTransformer = NULL; - m_bRgbByteOrder = FALSE; - m_BlendType = FXDIB_BLEND_NORMAL; +void CFX_FilteredDIB::DownSampleScanline(int line, + uint8_t* dest_scan, + int dest_bpp, + int dest_width, + FX_BOOL bFlipX, + int clip_left, + int clip_width) const { + m_pSrc->DownSampleScanline(line, dest_scan, dest_bpp, dest_width, bFlipX, + clip_left, clip_width); + TranslateDownSamples(dest_scan, dest_scan, clip_width, dest_bpp); } -CFX_ImageRenderer::~CFX_ImageRenderer() -{ - delete m_pTransformer; +CFX_ImageRenderer::CFX_ImageRenderer() { + m_Status = 0; + m_pTransformer = NULL; + m_bRgbByteOrder = FALSE; + m_BlendType = FXDIB_BLEND_NORMAL; } -extern FX_RECT _FXDIB_SwapClipBox(FX_RECT& clip, int width, int height, FX_BOOL bFlipX, FX_BOOL bFlipY); -FX_BOOL CFX_ImageRenderer::Start(CFX_DIBitmap* pDevice, const CFX_ClipRgn* pClipRgn, - const CFX_DIBSource* pSource, int bitmap_alpha, - FX_DWORD mask_color, const CFX_AffineMatrix* pMatrix, - FX_DWORD dib_flags, FX_BOOL bRgbByteOrder, - int alpha_flag, void* pIccTransform, int blend_type) -{ - m_Matrix = *pMatrix; - CFX_FloatRect image_rect_f = m_Matrix.GetUnitRect(); - FX_RECT image_rect = image_rect_f.GetOutterRect(); - m_ClipBox = pClipRgn ? pClipRgn->GetBox() : FX_RECT(0, 0, pDevice->GetWidth(), pDevice->GetHeight()); - m_ClipBox.Intersect(image_rect); - if (m_ClipBox.IsEmpty()) { - return FALSE; - } - m_pDevice = pDevice; - m_pClipRgn = pClipRgn; - m_MaskColor = mask_color; - m_BitmapAlpha = bitmap_alpha; - m_Matrix = *pMatrix; - m_Flags = dib_flags; - m_AlphaFlag = alpha_flag; - m_pIccTransform = pIccTransform; - m_bRgbByteOrder = bRgbByteOrder; - m_BlendType = blend_type; - FX_BOOL ret = TRUE; - if ((FXSYS_fabs(m_Matrix.b) >= 0.5f || m_Matrix.a == 0) || - (FXSYS_fabs(m_Matrix.c) >= 0.5f || m_Matrix.d == 0) ) { - if (FXSYS_fabs(m_Matrix.a) < FXSYS_fabs(m_Matrix.b) / 20 && FXSYS_fabs(m_Matrix.d) < FXSYS_fabs(m_Matrix.c) / 20 && - FXSYS_fabs(m_Matrix.a) < 0.5f && FXSYS_fabs(m_Matrix.d) < 0.5f) { - int dest_width = image_rect.Width(); - int dest_height = image_rect.Height(); - FX_RECT bitmap_clip = m_ClipBox; - bitmap_clip.Offset(-image_rect.left, -image_rect.top); - bitmap_clip = _FXDIB_SwapClipBox(bitmap_clip, dest_width, dest_height, m_Matrix.c > 0, m_Matrix.b < 0); - m_Composer.Compose(pDevice, pClipRgn, bitmap_alpha, mask_color, m_ClipBox, TRUE, - m_Matrix.c > 0, m_Matrix.b < 0, m_bRgbByteOrder, alpha_flag, pIccTransform, m_BlendType); - if (!m_Stretcher.Start(&m_Composer, pSource, dest_height, dest_width, bitmap_clip, dib_flags)) { - return FALSE; - } - m_Status = 1; - return TRUE; - } - m_Status = 2; - m_pTransformer = new CFX_ImageTransformer; - m_pTransformer->Start(pSource, &m_Matrix, dib_flags, &m_ClipBox); - return TRUE; - } - int dest_width = image_rect.Width(); - if (m_Matrix.a < 0) { - dest_width = -dest_width; - } - int dest_height = image_rect.Height(); - if (m_Matrix.d > 0) { - dest_height = -dest_height; - } - if (dest_width == 0 || dest_height == 0) { +CFX_ImageRenderer::~CFX_ImageRenderer() { + delete m_pTransformer; +} +extern FX_RECT _FXDIB_SwapClipBox(FX_RECT& clip, + int width, + int height, + FX_BOOL bFlipX, + FX_BOOL bFlipY); +FX_BOOL CFX_ImageRenderer::Start(CFX_DIBitmap* pDevice, + const CFX_ClipRgn* pClipRgn, + const CFX_DIBSource* pSource, + int bitmap_alpha, + FX_DWORD mask_color, + const CFX_AffineMatrix* pMatrix, + FX_DWORD dib_flags, + FX_BOOL bRgbByteOrder, + int alpha_flag, + void* pIccTransform, + int blend_type) { + m_Matrix = *pMatrix; + CFX_FloatRect image_rect_f = m_Matrix.GetUnitRect(); + FX_RECT image_rect = image_rect_f.GetOutterRect(); + m_ClipBox = pClipRgn ? pClipRgn->GetBox() : FX_RECT(0, 0, pDevice->GetWidth(), + pDevice->GetHeight()); + m_ClipBox.Intersect(image_rect); + if (m_ClipBox.IsEmpty()) { + return FALSE; + } + m_pDevice = pDevice; + m_pClipRgn = pClipRgn; + m_MaskColor = mask_color; + m_BitmapAlpha = bitmap_alpha; + m_Matrix = *pMatrix; + m_Flags = dib_flags; + m_AlphaFlag = alpha_flag; + m_pIccTransform = pIccTransform; + m_bRgbByteOrder = bRgbByteOrder; + m_BlendType = blend_type; + FX_BOOL ret = TRUE; + if ((FXSYS_fabs(m_Matrix.b) >= 0.5f || m_Matrix.a == 0) || + (FXSYS_fabs(m_Matrix.c) >= 0.5f || m_Matrix.d == 0)) { + if (FXSYS_fabs(m_Matrix.a) < FXSYS_fabs(m_Matrix.b) / 20 && + FXSYS_fabs(m_Matrix.d) < FXSYS_fabs(m_Matrix.c) / 20 && + FXSYS_fabs(m_Matrix.a) < 0.5f && FXSYS_fabs(m_Matrix.d) < 0.5f) { + int dest_width = image_rect.Width(); + int dest_height = image_rect.Height(); + FX_RECT bitmap_clip = m_ClipBox; + bitmap_clip.Offset(-image_rect.left, -image_rect.top); + bitmap_clip = _FXDIB_SwapClipBox(bitmap_clip, dest_width, dest_height, + m_Matrix.c > 0, m_Matrix.b < 0); + m_Composer.Compose(pDevice, pClipRgn, bitmap_alpha, mask_color, m_ClipBox, + TRUE, m_Matrix.c > 0, m_Matrix.b < 0, m_bRgbByteOrder, + alpha_flag, pIccTransform, m_BlendType); + if (!m_Stretcher.Start(&m_Composer, pSource, dest_height, dest_width, + bitmap_clip, dib_flags)) { return FALSE; + } + m_Status = 1; + return TRUE; } - FX_RECT bitmap_clip = m_ClipBox; - bitmap_clip.Offset(-image_rect.left, -image_rect.top); - m_Composer.Compose(pDevice, pClipRgn, bitmap_alpha, mask_color, - m_ClipBox, FALSE, FALSE, FALSE, m_bRgbByteOrder, alpha_flag, pIccTransform, m_BlendType); - m_Status = 1; - ret = m_Stretcher.Start(&m_Composer, pSource, dest_width, dest_height, bitmap_clip, dib_flags); - return ret; + m_Status = 2; + m_pTransformer = new CFX_ImageTransformer; + m_pTransformer->Start(pSource, &m_Matrix, dib_flags, &m_ClipBox); + return TRUE; + } + int dest_width = image_rect.Width(); + if (m_Matrix.a < 0) { + dest_width = -dest_width; + } + int dest_height = image_rect.Height(); + if (m_Matrix.d > 0) { + dest_height = -dest_height; + } + if (dest_width == 0 || dest_height == 0) { + return FALSE; + } + FX_RECT bitmap_clip = m_ClipBox; + bitmap_clip.Offset(-image_rect.left, -image_rect.top); + m_Composer.Compose(pDevice, pClipRgn, bitmap_alpha, mask_color, m_ClipBox, + FALSE, FALSE, FALSE, m_bRgbByteOrder, alpha_flag, + pIccTransform, m_BlendType); + m_Status = 1; + ret = m_Stretcher.Start(&m_Composer, pSource, dest_width, dest_height, + bitmap_clip, dib_flags); + return ret; } -FX_BOOL CFX_ImageRenderer::Continue(IFX_Pause* pPause) -{ - if (m_Status == 1) { - return m_Stretcher.Continue(pPause); - } - if (m_Status == 2) { - if (m_pTransformer->Continue(pPause)) { - return TRUE; - } - CFX_DIBitmap* pBitmap = m_pTransformer->m_Storer.Detach(); - if (pBitmap == NULL) { - return FALSE; - } - if (pBitmap->GetBuffer() == NULL) { - delete pBitmap; - return FALSE; - } - if (pBitmap->IsAlphaMask()) { - if (m_BitmapAlpha != 255) { - if (m_AlphaFlag >> 8) { - m_AlphaFlag = (((uint8_t)((m_AlphaFlag & 0xff) * m_BitmapAlpha / 255)) | ((m_AlphaFlag >> 8) << 8)); - } else { - m_MaskColor = FXARGB_MUL_ALPHA(m_MaskColor, m_BitmapAlpha); - } - } - m_pDevice->CompositeMask(m_pTransformer->m_ResultLeft, m_pTransformer->m_ResultTop, - pBitmap->GetWidth(), pBitmap->GetHeight(), pBitmap, m_MaskColor, - 0, 0, m_BlendType, m_pClipRgn, m_bRgbByteOrder, m_AlphaFlag, m_pIccTransform); +FX_BOOL CFX_ImageRenderer::Continue(IFX_Pause* pPause) { + if (m_Status == 1) { + return m_Stretcher.Continue(pPause); + } + if (m_Status == 2) { + if (m_pTransformer->Continue(pPause)) { + return TRUE; + } + CFX_DIBitmap* pBitmap = m_pTransformer->m_Storer.Detach(); + if (pBitmap == NULL) { + return FALSE; + } + if (pBitmap->GetBuffer() == NULL) { + delete pBitmap; + return FALSE; + } + if (pBitmap->IsAlphaMask()) { + if (m_BitmapAlpha != 255) { + if (m_AlphaFlag >> 8) { + m_AlphaFlag = + (((uint8_t)((m_AlphaFlag & 0xff) * m_BitmapAlpha / 255)) | + ((m_AlphaFlag >> 8) << 8)); } else { - if (m_BitmapAlpha != 255) { - pBitmap->MultiplyAlpha(m_BitmapAlpha); - } - m_pDevice->CompositeBitmap(m_pTransformer->m_ResultLeft, m_pTransformer->m_ResultTop, - pBitmap->GetWidth(), pBitmap->GetHeight(), pBitmap, 0, 0, m_BlendType, m_pClipRgn, m_bRgbByteOrder, m_pIccTransform); - } - delete pBitmap; - return FALSE; - } + m_MaskColor = FXARGB_MUL_ALPHA(m_MaskColor, m_BitmapAlpha); + } + } + m_pDevice->CompositeMask(m_pTransformer->m_ResultLeft, + m_pTransformer->m_ResultTop, pBitmap->GetWidth(), + pBitmap->GetHeight(), pBitmap, m_MaskColor, 0, 0, + m_BlendType, m_pClipRgn, m_bRgbByteOrder, + m_AlphaFlag, m_pIccTransform); + } else { + if (m_BitmapAlpha != 255) { + pBitmap->MultiplyAlpha(m_BitmapAlpha); + } + m_pDevice->CompositeBitmap( + m_pTransformer->m_ResultLeft, m_pTransformer->m_ResultTop, + pBitmap->GetWidth(), pBitmap->GetHeight(), pBitmap, 0, 0, m_BlendType, + m_pClipRgn, m_bRgbByteOrder, m_pIccTransform); + } + delete pBitmap; return FALSE; + } + return FALSE; } -CFX_BitmapStorer::CFX_BitmapStorer() -{ - m_pBitmap = NULL; +CFX_BitmapStorer::CFX_BitmapStorer() { + m_pBitmap = NULL; } -CFX_BitmapStorer::~CFX_BitmapStorer() -{ - delete m_pBitmap; +CFX_BitmapStorer::~CFX_BitmapStorer() { + delete m_pBitmap; } -CFX_DIBitmap* CFX_BitmapStorer::Detach() -{ - CFX_DIBitmap* pBitmap = m_pBitmap; - m_pBitmap = NULL; - return pBitmap; +CFX_DIBitmap* CFX_BitmapStorer::Detach() { + CFX_DIBitmap* pBitmap = m_pBitmap; + m_pBitmap = NULL; + return pBitmap; } -void CFX_BitmapStorer::Replace(CFX_DIBitmap* pBitmap) -{ - delete m_pBitmap; - m_pBitmap = pBitmap; +void CFX_BitmapStorer::Replace(CFX_DIBitmap* pBitmap) { + delete m_pBitmap; + m_pBitmap = pBitmap; } -void CFX_BitmapStorer::ComposeScanline(int line, const uint8_t* scanline, const uint8_t* scan_extra_alpha) -{ - uint8_t* dest_buf = (uint8_t*)m_pBitmap->GetScanline(line); - uint8_t* dest_alpha_buf = m_pBitmap->m_pAlphaMask ? - (uint8_t*)m_pBitmap->m_pAlphaMask->GetScanline(line) : NULL; - if (dest_buf) { - FXSYS_memcpy(dest_buf, scanline, m_pBitmap->GetPitch()); - } - if (dest_alpha_buf) { - FXSYS_memcpy(dest_alpha_buf, scan_extra_alpha, m_pBitmap->m_pAlphaMask->GetPitch()); - } +void CFX_BitmapStorer::ComposeScanline(int line, + const uint8_t* scanline, + const uint8_t* scan_extra_alpha) { + uint8_t* dest_buf = (uint8_t*)m_pBitmap->GetScanline(line); + uint8_t* dest_alpha_buf = + m_pBitmap->m_pAlphaMask + ? (uint8_t*)m_pBitmap->m_pAlphaMask->GetScanline(line) + : NULL; + if (dest_buf) { + FXSYS_memcpy(dest_buf, scanline, m_pBitmap->GetPitch()); + } + if (dest_alpha_buf) { + FXSYS_memcpy(dest_alpha_buf, scan_extra_alpha, + m_pBitmap->m_pAlphaMask->GetPitch()); + } } -FX_BOOL CFX_BitmapStorer::SetInfo(int width, int height, FXDIB_Format src_format, FX_DWORD* pSrcPalette) -{ - m_pBitmap = new CFX_DIBitmap; - if (!m_pBitmap->Create(width, height, src_format)) { - delete m_pBitmap; - m_pBitmap = NULL; - return FALSE; - } - if (pSrcPalette) { - m_pBitmap->CopyPalette(pSrcPalette); - } - return TRUE; +FX_BOOL CFX_BitmapStorer::SetInfo(int width, + int height, + FXDIB_Format src_format, + FX_DWORD* pSrcPalette) { + m_pBitmap = new CFX_DIBitmap; + if (!m_pBitmap->Create(width, height, src_format)) { + delete m_pBitmap; + m_pBitmap = NULL; + return FALSE; + } + if (pSrcPalette) { + m_pBitmap->CopyPalette(pSrcPalette); + } + return TRUE; } diff --git a/core/src/fxge/dib/fx_dib_transform.cpp b/core/src/fxge/dib/fx_dib_transform.cpp index e34e715bf2..887964ba00 100644 --- a/core/src/fxge/dib/fx_dib_transform.cpp +++ b/core/src/fxge/dib/fx_dib_transform.cpp @@ -7,784 +7,932 @@ #include "../../../include/fxge/fx_dib.h" #include "dib_int.h" int SDP_Table[513] = { - 256, 256, 256, 256, 256, 256, 256, 256, 256, 255, 255, 255, 255, 255, 255, 254, 254, 254, 254, - 253, 253, 253, 252, 252, 252, 251, 251, 251, 250, 250, 249, 249, 249, 248, 248, 247, 247, 246, - 246, 245, 244, 244, 243, 243, 242, 242, 241, 240, 240, 239, 238, 238, 237, 236, 236, 235, 234, - 233, 233, 232, 231, 230, 230, 229, 228, 227, 226, 226, 225, 224, 223, 222, 221, 220, 219, 218, - 218, 217, 216, 215, 214, 213, 212, 211, 210, 209, 208, 207, 206, 205, 204, 203, 202, 201, 200, - 199, 198, 196, 195, 194, 193, 192, 191, 190, 189, 188, 186, 185, 184, 183, 182, 181, 179, 178, - 177, 176, 175, 173, 172, 171, 170, 169, 167, 166, 165, 164, 162, 161, 160, 159, 157, 156, 155, - 154, 152, 151, 150, 149, 147, 146, 145, 143, 142, 141, 140, 138, 137, 136, 134, 133, 132, 130, - 129, 128, 126, 125, 124, 122, 121, 120, 119, 117, 116, 115, 113, 112, 111, 109, 108, 107, 105, - 104, 103, 101, 100, 99, 97, 96, 95, 93, 92, 91, 89, 88, 87, 85, 84, 83, 81, 80, 79, 77, 76, 75, - 73, 72, 71, 69, 68, 67, 66, 64, 63, 62, 60, 59, 58, 57, 55, 54, 53, 52, 50, 49, 48, 47, 45, 44, - 43, 42, 40, 39, 38, 37, 36, 34, 33, 32, 31, 30, 28, 27, 26, 25, 24, 23, 21, 20, 19, 18, 17, 16, - 15, 14, 13, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, -1, -2, -3, -4, -5, -6, -7, -7, -8, -9, -10, - -11, -12, -12, -13, -14, -15, -15, -16, -17, -17, -18, -19, -19, -20, -21, -21, -22, -22, -23, -24, - -24, -25, -25, -26, -26, -27, -27, -27, -28, -28, -29, -29, -30, -30, -30, -31, -31, -31, -32, -32, - -32, -33, -33, -33, -33, -34, -34, -34, -34, -35, -35, -35, -35, -35, -36, -36, -36, -36, -36, -36, - -36, -36, -36, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, - -37, -37, -37, -37, -36, -36, -36, -36, -36, -36, -36, -36, -36, -35, -35, -35, -35, -35, -35, -34, - -34, -34, -34, -34, -33, -33, -33, -33, -33, -32, -32, -32, -32, -31, -31, -31, -31, -30, -30, -30, - -30, -29, -29, -29, -29, -28, -28, -28, -27, -27, -27, -27, -26, -26, -26, -25, -25, -25, -24, -24, - -24, -23, -23, -23, -22, -22, -22, -22, -21, -21, -21, -20, -20, -20, -19, -19, -19, -18, -18, -18, - -17, -17, -17, -16, -16, -16, -15, -15, -15, -14, -14, -14, -13, -13, -13, -12, -12, -12, -11, -11, - -11, -10, -10, -10, -9, -9, -9, -9, -8, -8, -8, -7, -7, -7, -7, -6, -6, -6, -6, -5, -5, -5, -5, -4, - -4, -4, -4, -3, -3, -3, -3, -3, -2, -2, -2, -2, -2, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 256, 256, 256, 256, 256, 256, 256, 256, 256, 255, 255, 255, 255, 255, 255, + 254, 254, 254, 254, 253, 253, 253, 252, 252, 252, 251, 251, 251, 250, 250, + 249, 249, 249, 248, 248, 247, 247, 246, 246, 245, 244, 244, 243, 243, 242, + 242, 241, 240, 240, 239, 238, 238, 237, 236, 236, 235, 234, 233, 233, 232, + 231, 230, 230, 229, 228, 227, 226, 226, 225, 224, 223, 222, 221, 220, 219, + 218, 218, 217, 216, 215, 214, 213, 212, 211, 210, 209, 208, 207, 206, 205, + 204, 203, 202, 201, 200, 199, 198, 196, 195, 194, 193, 192, 191, 190, 189, + 188, 186, 185, 184, 183, 182, 181, 179, 178, 177, 176, 175, 173, 172, 171, + 170, 169, 167, 166, 165, 164, 162, 161, 160, 159, 157, 156, 155, 154, 152, + 151, 150, 149, 147, 146, 145, 143, 142, 141, 140, 138, 137, 136, 134, 133, + 132, 130, 129, 128, 126, 125, 124, 122, 121, 120, 119, 117, 116, 115, 113, + 112, 111, 109, 108, 107, 105, 104, 103, 101, 100, 99, 97, 96, 95, 93, + 92, 91, 89, 88, 87, 85, 84, 83, 81, 80, 79, 77, 76, 75, 73, + 72, 71, 69, 68, 67, 66, 64, 63, 62, 60, 59, 58, 57, 55, 54, + 53, 52, 50, 49, 48, 47, 45, 44, 43, 42, 40, 39, 38, 37, 36, + 34, 33, 32, 31, 30, 28, 27, 26, 25, 24, 23, 21, 20, 19, 18, + 17, 16, 15, 14, 13, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, + 1, 0, 0, -1, -2, -3, -4, -5, -6, -7, -7, -8, -9, -10, -11, + -12, -12, -13, -14, -15, -15, -16, -17, -17, -18, -19, -19, -20, -21, -21, + -22, -22, -23, -24, -24, -25, -25, -26, -26, -27, -27, -27, -28, -28, -29, + -29, -30, -30, -30, -31, -31, -31, -32, -32, -32, -33, -33, -33, -33, -34, + -34, -34, -34, -35, -35, -35, -35, -35, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -36, -36, -36, -36, -36, -36, -36, + -36, -36, -35, -35, -35, -35, -35, -35, -34, -34, -34, -34, -34, -33, -33, + -33, -33, -33, -32, -32, -32, -32, -31, -31, -31, -31, -30, -30, -30, -30, + -29, -29, -29, -29, -28, -28, -28, -27, -27, -27, -27, -26, -26, -26, -25, + -25, -25, -24, -24, -24, -23, -23, -23, -22, -22, -22, -22, -21, -21, -21, + -20, -20, -20, -19, -19, -19, -18, -18, -18, -17, -17, -17, -16, -16, -16, + -15, -15, -15, -14, -14, -14, -13, -13, -13, -12, -12, -12, -11, -11, -11, + -10, -10, -10, -9, -9, -9, -9, -8, -8, -8, -7, -7, -7, -7, -6, + -6, -6, -6, -5, -5, -5, -5, -4, -4, -4, -4, -3, -3, -3, -3, + -3, -2, -2, -2, -2, -2, -1, -1, -1, -1, -1, -1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, }; -class CFX_BilinearMatrix : public CPDF_FixedMatrix -{ -public: - CFX_BilinearMatrix(const CFX_AffineMatrix& src, int bits): CPDF_FixedMatrix(src, bits) - {} - inline void Transform(int x, int y, int& x1, int& y1, int&res_x, int&res_y) - { - x1 = a * x + c * y + e + base / 2; - y1 = b * x + d * y + f + base / 2; - res_x = x1 % base; - res_y = y1 % base; - if (res_x < 0 && res_x > -base) { - res_x = base + res_x; - } - if (res_y < 0 && res_x > -base) { - res_y = base + res_y; - } - x1 /= base; - y1 /= base; +class CFX_BilinearMatrix : public CPDF_FixedMatrix { + public: + CFX_BilinearMatrix(const CFX_AffineMatrix& src, int bits) + : CPDF_FixedMatrix(src, bits) {} + inline void Transform(int x, + int y, + int& x1, + int& y1, + int& res_x, + int& res_y) { + x1 = a * x + c * y + e + base / 2; + y1 = b * x + d * y + f + base / 2; + res_x = x1 % base; + res_y = y1 % base; + if (res_x < 0 && res_x > -base) { + res_x = base + res_x; } -}; -CFX_DIBitmap* CFX_DIBSource::SwapXY(FX_BOOL bXFlip, FX_BOOL bYFlip, const FX_RECT* pDestClip) const -{ - FX_RECT dest_clip(0, 0, m_Height, m_Width); - if (pDestClip) { - dest_clip.Intersect(*pDestClip); + if (res_y < 0 && res_x > -base) { + res_y = base + res_y; } - if (dest_clip.IsEmpty()) { - return NULL; + x1 /= base; + y1 /= base; + } +}; +CFX_DIBitmap* CFX_DIBSource::SwapXY(FX_BOOL bXFlip, + FX_BOOL bYFlip, + const FX_RECT* pDestClip) const { + FX_RECT dest_clip(0, 0, m_Height, m_Width); + if (pDestClip) { + dest_clip.Intersect(*pDestClip); + } + if (dest_clip.IsEmpty()) { + return NULL; + } + CFX_DIBitmap* pTransBitmap = new CFX_DIBitmap; + int result_height = dest_clip.Height(), result_width = dest_clip.Width(); + if (!pTransBitmap->Create(result_width, result_height, GetFormat())) { + delete pTransBitmap; + return NULL; + } + pTransBitmap->CopyPalette(m_pPalette); + int dest_pitch = pTransBitmap->GetPitch(); + uint8_t* dest_buf = pTransBitmap->GetBuffer(); + int row_start = bXFlip ? m_Height - dest_clip.right : dest_clip.left; + int row_end = bXFlip ? m_Height - dest_clip.left : dest_clip.right; + int col_start = bYFlip ? m_Width - dest_clip.bottom : dest_clip.top; + int col_end = bYFlip ? m_Width - dest_clip.top : dest_clip.bottom; + if (GetBPP() == 1) { + FXSYS_memset(dest_buf, 0xff, dest_pitch * result_height); + for (int row = row_start; row < row_end; row++) { + const uint8_t* src_scan = GetScanline(row); + int dest_col = (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) - + dest_clip.left; + uint8_t* dest_scan = dest_buf; + if (bYFlip) { + dest_scan += (result_height - 1) * dest_pitch; + } + int dest_step = bYFlip ? -dest_pitch : dest_pitch; + for (int col = col_start; col < col_end; col++) { + if (!(src_scan[col / 8] & (1 << (7 - col % 8)))) { + dest_scan[dest_col / 8] &= ~(1 << (7 - dest_col % 8)); + } + dest_scan += dest_step; + } } - CFX_DIBitmap* pTransBitmap = new CFX_DIBitmap; - int result_height = dest_clip.Height(), result_width = dest_clip.Width(); - if (!pTransBitmap->Create(result_width, result_height, GetFormat())) { - delete pTransBitmap; - return NULL; + } else { + int nBytes = GetBPP() / 8; + int dest_step = bYFlip ? -dest_pitch : dest_pitch; + if (nBytes == 3) { + dest_step -= 2; } - pTransBitmap->CopyPalette(m_pPalette); - int dest_pitch = pTransBitmap->GetPitch(); - uint8_t* dest_buf = pTransBitmap->GetBuffer(); - int row_start = bXFlip ? m_Height - dest_clip.right : dest_clip.left; - int row_end = bXFlip ? m_Height - dest_clip.left : dest_clip.right; - int col_start = bYFlip ? m_Width - dest_clip.bottom : dest_clip.top; - int col_end = bYFlip ? m_Width - dest_clip.top : dest_clip.bottom; - if (GetBPP() == 1) { - FXSYS_memset(dest_buf, 0xff, dest_pitch * result_height); - for (int row = row_start; row < row_end; row ++) { - const uint8_t* src_scan = GetScanline(row); - int dest_col = (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) - dest_clip.left; - uint8_t* dest_scan = dest_buf; - if (bYFlip) { - dest_scan += (result_height - 1) * dest_pitch; - } - int dest_step = bYFlip ? -dest_pitch : dest_pitch; - for (int col = col_start; col < col_end; col ++) { - if (!(src_scan[col / 8] & (1 << (7 - col % 8)))) { - dest_scan[dest_col / 8] &= ~(1 << (7 - dest_col % 8)); - } - dest_scan += dest_step; - } - } - } else { - int nBytes = GetBPP() / 8; - int dest_step = bYFlip ? -dest_pitch : dest_pitch; - if (nBytes == 3) { - dest_step -= 2; - } - for (int row = row_start; row < row_end; row ++) { - int dest_col = (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) - dest_clip.left; - uint8_t* dest_scan = dest_buf + dest_col * nBytes; - if (bYFlip) { - dest_scan += (result_height - 1) * dest_pitch; - } - if (nBytes == 4) { - FX_DWORD* src_scan = (FX_DWORD*)GetScanline(row) + col_start; - for (int col = col_start; col < col_end; col ++) { - *(FX_DWORD*)dest_scan = *src_scan++; - dest_scan += dest_step; - } - } else { - const uint8_t* src_scan = GetScanline(row) + col_start * nBytes; - if (nBytes == 1) - for (int col = col_start; col < col_end; col ++) { - *dest_scan = *src_scan++; - dest_scan += dest_step; - } - else - for (int col = col_start; col < col_end; col ++) { - *dest_scan++ = *src_scan++; - *dest_scan++ = *src_scan++; - *dest_scan = *src_scan++; - dest_scan += dest_step; - } - } + for (int row = row_start; row < row_end; row++) { + int dest_col = (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) - + dest_clip.left; + uint8_t* dest_scan = dest_buf + dest_col * nBytes; + if (bYFlip) { + dest_scan += (result_height - 1) * dest_pitch; + } + if (nBytes == 4) { + FX_DWORD* src_scan = (FX_DWORD*)GetScanline(row) + col_start; + for (int col = col_start; col < col_end; col++) { + *(FX_DWORD*)dest_scan = *src_scan++; + dest_scan += dest_step; } + } else { + const uint8_t* src_scan = GetScanline(row) + col_start * nBytes; + if (nBytes == 1) + for (int col = col_start; col < col_end; col++) { + *dest_scan = *src_scan++; + dest_scan += dest_step; + } + else + for (int col = col_start; col < col_end; col++) { + *dest_scan++ = *src_scan++; + *dest_scan++ = *src_scan++; + *dest_scan = *src_scan++; + dest_scan += dest_step; + } + } } - if (m_pAlphaMask) { - dest_pitch = pTransBitmap->m_pAlphaMask->GetPitch(); - dest_buf = pTransBitmap->m_pAlphaMask->GetBuffer(); - int dest_step = bYFlip ? -dest_pitch : dest_pitch; - for (int row = row_start; row < row_end; row ++) { - int dest_col = (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) - dest_clip.left; - uint8_t* dest_scan = dest_buf + dest_col; - if (bYFlip) { - dest_scan += (result_height - 1) * dest_pitch; - } - const uint8_t* src_scan = m_pAlphaMask->GetScanline(row) + col_start; - for (int col = col_start; col < col_end; col ++) { - *dest_scan = *src_scan++; - dest_scan += dest_step; - } - } + } + if (m_pAlphaMask) { + dest_pitch = pTransBitmap->m_pAlphaMask->GetPitch(); + dest_buf = pTransBitmap->m_pAlphaMask->GetBuffer(); + int dest_step = bYFlip ? -dest_pitch : dest_pitch; + for (int row = row_start; row < row_end; row++) { + int dest_col = (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) - + dest_clip.left; + uint8_t* dest_scan = dest_buf + dest_col; + if (bYFlip) { + dest_scan += (result_height - 1) * dest_pitch; + } + const uint8_t* src_scan = m_pAlphaMask->GetScanline(row) + col_start; + for (int col = col_start; col < col_end; col++) { + *dest_scan = *src_scan++; + dest_scan += dest_step; + } } - return pTransBitmap; + } + return pTransBitmap; } #define FIX16_005 0.05f -FX_RECT _FXDIB_SwapClipBox(FX_RECT& clip, int width, int height, FX_BOOL bFlipX, FX_BOOL bFlipY) -{ - FX_RECT rect; - if (bFlipY) { - rect.left = height - clip.top; - rect.right = height - clip.bottom; - } else { - rect.left = clip.top; - rect.right = clip.bottom; - } - if (bFlipX) { - rect.top = width - clip.left; - rect.bottom = width - clip.right; - } else { - rect.top = clip.left; - rect.bottom = clip.right; - } - rect.Normalize(); - return rect; -} -CFX_DIBitmap* CFX_DIBSource::TransformTo(const CFX_AffineMatrix* pDestMatrix, int& result_left, int& result_top, - FX_DWORD flags, const FX_RECT* pDestClip) const -{ - CFX_ImageTransformer transformer; - transformer.Start(this, pDestMatrix, flags, pDestClip); - transformer.Continue(NULL); - result_left = transformer.m_ResultLeft; - result_top = transformer.m_ResultTop; - CFX_DIBitmap* pTransformed = transformer.m_Storer.Detach(); - return pTransformed; +FX_RECT _FXDIB_SwapClipBox(FX_RECT& clip, + int width, + int height, + FX_BOOL bFlipX, + FX_BOOL bFlipY) { + FX_RECT rect; + if (bFlipY) { + rect.left = height - clip.top; + rect.right = height - clip.bottom; + } else { + rect.left = clip.top; + rect.right = clip.bottom; + } + if (bFlipX) { + rect.top = width - clip.left; + rect.bottom = width - clip.right; + } else { + rect.top = clip.left; + rect.bottom = clip.right; + } + rect.Normalize(); + return rect; } -CFX_DIBitmap* CFX_DIBSource::StretchTo(int dest_width, int dest_height, FX_DWORD flags, const FX_RECT* pClip) const -{ - FX_RECT clip_rect(0, 0, FXSYS_abs(dest_width), FXSYS_abs(dest_height)); - if (pClip) { - clip_rect.Intersect(*pClip); - } - if (clip_rect.IsEmpty()) { - return NULL; - } - if (dest_width == m_Width && dest_height == m_Height) { - return Clone(&clip_rect); - } - CFX_ImageStretcher stretcher; - CFX_BitmapStorer storer; - if (stretcher.Start(&storer, this, dest_width, dest_height, clip_rect, flags)) { - stretcher.Continue(NULL); - } - return storer.Detach(); +CFX_DIBitmap* CFX_DIBSource::TransformTo(const CFX_AffineMatrix* pDestMatrix, + int& result_left, + int& result_top, + FX_DWORD flags, + const FX_RECT* pDestClip) const { + CFX_ImageTransformer transformer; + transformer.Start(this, pDestMatrix, flags, pDestClip); + transformer.Continue(NULL); + result_left = transformer.m_ResultLeft; + result_top = transformer.m_ResultTop; + CFX_DIBitmap* pTransformed = transformer.m_Storer.Detach(); + return pTransformed; } -CFX_ImageTransformer::CFX_ImageTransformer() -{ - m_Status = 0; - m_pMatrix = NULL; +CFX_DIBitmap* CFX_DIBSource::StretchTo(int dest_width, + int dest_height, + FX_DWORD flags, + const FX_RECT* pClip) const { + FX_RECT clip_rect(0, 0, FXSYS_abs(dest_width), FXSYS_abs(dest_height)); + if (pClip) { + clip_rect.Intersect(*pClip); + } + if (clip_rect.IsEmpty()) { + return NULL; + } + if (dest_width == m_Width && dest_height == m_Height) { + return Clone(&clip_rect); + } + CFX_ImageStretcher stretcher; + CFX_BitmapStorer storer; + if (stretcher.Start(&storer, this, dest_width, dest_height, clip_rect, + flags)) { + stretcher.Continue(NULL); + } + return storer.Detach(); } -CFX_ImageTransformer::~CFX_ImageTransformer() -{ +CFX_ImageTransformer::CFX_ImageTransformer() { + m_Status = 0; + m_pMatrix = NULL; } -FX_BOOL CFX_ImageTransformer::Start(const CFX_DIBSource* pSrc, const CFX_AffineMatrix* pDestMatrix, int flags, const FX_RECT* pDestClip) -{ - m_pMatrix = (CFX_AffineMatrix*)pDestMatrix; - CFX_FloatRect unit_rect = pDestMatrix->GetUnitRect(); - FX_RECT result_rect = unit_rect.GetClosestRect(); - FX_RECT result_clip = result_rect; - if (pDestClip) { - result_clip.Intersect(*pDestClip); - } - if (result_clip.IsEmpty()) { - return FALSE; - } - m_ResultLeft = result_clip.left; - m_ResultTop = result_clip.top; - m_ResultWidth = result_clip.Width(); - m_ResultHeight = result_clip.Height(); - m_Flags = flags; - if (FXSYS_fabs(pDestMatrix->a) < FXSYS_fabs(pDestMatrix->b) / 20 && - FXSYS_fabs(pDestMatrix->d) < FXSYS_fabs(pDestMatrix->c) / 20 && - FXSYS_fabs(pDestMatrix->a) < 0.5f && FXSYS_fabs(pDestMatrix->d) < 0.5f) { - int dest_width = result_rect.Width(); - int dest_height = result_rect.Height(); - result_clip.Offset(-result_rect.left, -result_rect.top); - result_clip = _FXDIB_SwapClipBox(result_clip, dest_width, dest_height, pDestMatrix->c > 0, pDestMatrix->b < 0); - m_Stretcher.Start(&m_Storer, pSrc, dest_height, dest_width, result_clip, flags); - m_Status = 1; - return TRUE; - } - if (FXSYS_fabs(pDestMatrix->b) < FIX16_005 && FXSYS_fabs(pDestMatrix->c) < FIX16_005) { - int dest_width = pDestMatrix->a > 0 ? (int)FXSYS_ceil(pDestMatrix->a) : (int)FXSYS_floor(pDestMatrix->a); - int dest_height = pDestMatrix->d > 0 ? (int) - FXSYS_ceil(pDestMatrix->d) : (int) - FXSYS_floor(pDestMatrix->d); - result_clip.Offset(-result_rect.left, -result_rect.top); - m_Stretcher.Start(&m_Storer, pSrc, dest_width, dest_height, result_clip, flags); - m_Status = 2; - return TRUE; - } - int stretch_width = (int)FXSYS_ceil(FXSYS_sqrt2(pDestMatrix->a, pDestMatrix->b)); - int stretch_height = (int)FXSYS_ceil(FXSYS_sqrt2(pDestMatrix->c, pDestMatrix->d)); - CFX_AffineMatrix stretch2dest(1.0f, 0.0f, 0.0f, -1.0f, 0.0f, (FX_FLOAT)(stretch_height)); - stretch2dest.Concat(pDestMatrix->a / stretch_width, pDestMatrix->b / stretch_width, - pDestMatrix->c / stretch_height, pDestMatrix->d / stretch_height, pDestMatrix->e, pDestMatrix->f); - m_dest2stretch.SetReverse(stretch2dest); - CFX_FloatRect clip_rect_f(result_clip); - clip_rect_f.Transform(&m_dest2stretch); - m_StretchClip = clip_rect_f.GetOutterRect(); - m_StretchClip.Intersect(0, 0, stretch_width, stretch_height); - m_Stretcher.Start(&m_Storer, pSrc, stretch_width, stretch_height, m_StretchClip, flags); - m_Status = 3; +CFX_ImageTransformer::~CFX_ImageTransformer() {} +FX_BOOL CFX_ImageTransformer::Start(const CFX_DIBSource* pSrc, + const CFX_AffineMatrix* pDestMatrix, + int flags, + const FX_RECT* pDestClip) { + m_pMatrix = (CFX_AffineMatrix*)pDestMatrix; + CFX_FloatRect unit_rect = pDestMatrix->GetUnitRect(); + FX_RECT result_rect = unit_rect.GetClosestRect(); + FX_RECT result_clip = result_rect; + if (pDestClip) { + result_clip.Intersect(*pDestClip); + } + if (result_clip.IsEmpty()) { + return FALSE; + } + m_ResultLeft = result_clip.left; + m_ResultTop = result_clip.top; + m_ResultWidth = result_clip.Width(); + m_ResultHeight = result_clip.Height(); + m_Flags = flags; + if (FXSYS_fabs(pDestMatrix->a) < FXSYS_fabs(pDestMatrix->b) / 20 && + FXSYS_fabs(pDestMatrix->d) < FXSYS_fabs(pDestMatrix->c) / 20 && + FXSYS_fabs(pDestMatrix->a) < 0.5f && FXSYS_fabs(pDestMatrix->d) < 0.5f) { + int dest_width = result_rect.Width(); + int dest_height = result_rect.Height(); + result_clip.Offset(-result_rect.left, -result_rect.top); + result_clip = _FXDIB_SwapClipBox(result_clip, dest_width, dest_height, + pDestMatrix->c > 0, pDestMatrix->b < 0); + m_Stretcher.Start(&m_Storer, pSrc, dest_height, dest_width, result_clip, + flags); + m_Status = 1; return TRUE; + } + if (FXSYS_fabs(pDestMatrix->b) < FIX16_005 && + FXSYS_fabs(pDestMatrix->c) < FIX16_005) { + int dest_width = pDestMatrix->a > 0 ? (int)FXSYS_ceil(pDestMatrix->a) + : (int)FXSYS_floor(pDestMatrix->a); + int dest_height = pDestMatrix->d > 0 ? (int)-FXSYS_ceil(pDestMatrix->d) + : (int)-FXSYS_floor(pDestMatrix->d); + result_clip.Offset(-result_rect.left, -result_rect.top); + m_Stretcher.Start(&m_Storer, pSrc, dest_width, dest_height, result_clip, + flags); + m_Status = 2; + return TRUE; + } + int stretch_width = + (int)FXSYS_ceil(FXSYS_sqrt2(pDestMatrix->a, pDestMatrix->b)); + int stretch_height = + (int)FXSYS_ceil(FXSYS_sqrt2(pDestMatrix->c, pDestMatrix->d)); + CFX_AffineMatrix stretch2dest(1.0f, 0.0f, 0.0f, -1.0f, 0.0f, + (FX_FLOAT)(stretch_height)); + stretch2dest.Concat( + pDestMatrix->a / stretch_width, pDestMatrix->b / stretch_width, + pDestMatrix->c / stretch_height, pDestMatrix->d / stretch_height, + pDestMatrix->e, pDestMatrix->f); + m_dest2stretch.SetReverse(stretch2dest); + CFX_FloatRect clip_rect_f(result_clip); + clip_rect_f.Transform(&m_dest2stretch); + m_StretchClip = clip_rect_f.GetOutterRect(); + m_StretchClip.Intersect(0, 0, stretch_width, stretch_height); + m_Stretcher.Start(&m_Storer, pSrc, stretch_width, stretch_height, + m_StretchClip, flags); + m_Status = 3; + return TRUE; } -uint8_t _bilinear_interpol(const uint8_t* buf, int row_offset_l, int row_offset_r, - int src_col_l, int src_col_r, int res_x, int res_y, - int bpp, int c_offset) -{ - int i_resx = 255 - res_x; - int col_bpp_l = src_col_l * bpp; - int col_bpp_r = src_col_r * bpp; - const uint8_t* buf_u = buf + row_offset_l + c_offset; - const uint8_t* buf_d = buf + row_offset_r + c_offset; - const uint8_t* src_pos0 = buf_u + col_bpp_l; - const uint8_t* src_pos1 = buf_u + col_bpp_r; - const uint8_t* src_pos2 = buf_d + col_bpp_l; - const uint8_t* src_pos3 = buf_d + col_bpp_r; - uint8_t r_pos_0 = (*src_pos0 * i_resx + *src_pos1 * res_x) >> 8; - uint8_t r_pos_1 = (*src_pos2 * i_resx + *src_pos3 * res_x) >> 8; - return (r_pos_0 * (255 - res_y) + r_pos_1 * res_y) >> 8; -} -uint8_t _bicubic_interpol(const uint8_t* buf, int pitch, int pos_pixel[], int u_w[], int v_w[], int res_x, int res_y, - int bpp, int c_offset) -{ - int s_result = 0; - for (int i = 0; i < 4; i ++) { - int a_result = 0; - for (int j = 0; j < 4; j ++) { - a_result += u_w[j] * (*(uint8_t*)(buf + pos_pixel[i + 4] * pitch + pos_pixel[j] * bpp + c_offset)); - } - s_result += a_result * v_w[i]; - } - s_result >>= 16; - return (uint8_t)(s_result < 0 ? 0 : s_result > 255 ? 255 : s_result); +uint8_t _bilinear_interpol(const uint8_t* buf, + int row_offset_l, + int row_offset_r, + int src_col_l, + int src_col_r, + int res_x, + int res_y, + int bpp, + int c_offset) { + int i_resx = 255 - res_x; + int col_bpp_l = src_col_l * bpp; + int col_bpp_r = src_col_r * bpp; + const uint8_t* buf_u = buf + row_offset_l + c_offset; + const uint8_t* buf_d = buf + row_offset_r + c_offset; + const uint8_t* src_pos0 = buf_u + col_bpp_l; + const uint8_t* src_pos1 = buf_u + col_bpp_r; + const uint8_t* src_pos2 = buf_d + col_bpp_l; + const uint8_t* src_pos3 = buf_d + col_bpp_r; + uint8_t r_pos_0 = (*src_pos0 * i_resx + *src_pos1 * res_x) >> 8; + uint8_t r_pos_1 = (*src_pos2 * i_resx + *src_pos3 * res_x) >> 8; + return (r_pos_0 * (255 - res_y) + r_pos_1 * res_y) >> 8; } -void _bicubic_get_pos_weight(int pos_pixel[], int u_w[], int v_w[], int src_col_l, int src_row_l, - int res_x, int res_y, int stretch_width, int stretch_height) -{ - pos_pixel[0] = src_col_l - 1; - pos_pixel[1] = src_col_l; - pos_pixel[2] = src_col_l + 1; - pos_pixel[3] = src_col_l + 2; - pos_pixel[4] = src_row_l - 1; - pos_pixel[5] = src_row_l; - pos_pixel[6] = src_row_l + 1; - pos_pixel[7] = src_row_l + 2; - for (int i = 0 ; i < 4; i ++) { - if (pos_pixel[i] < 0) { - pos_pixel[i] = 0; - } - if (pos_pixel[i] >= stretch_width) { - pos_pixel[i] = stretch_width - 1; - } - if (pos_pixel[i + 4] < 0) { - pos_pixel[i + 4] = 0; - } - if (pos_pixel[i + 4] >= stretch_height) { - pos_pixel[i + 4] = stretch_height - 1; - } +uint8_t _bicubic_interpol(const uint8_t* buf, + int pitch, + int pos_pixel[], + int u_w[], + int v_w[], + int res_x, + int res_y, + int bpp, + int c_offset) { + int s_result = 0; + for (int i = 0; i < 4; i++) { + int a_result = 0; + for (int j = 0; j < 4; j++) { + a_result += u_w[j] * (*(uint8_t*)(buf + pos_pixel[i + 4] * pitch + + pos_pixel[j] * bpp + c_offset)); } - u_w[0] = SDP_Table[256 + res_x]; - u_w[1] = SDP_Table[res_x]; - u_w[2] = SDP_Table[256 - res_x]; - u_w[3] = SDP_Table[512 - res_x]; - v_w[0] = SDP_Table[256 + res_y]; - v_w[1] = SDP_Table[res_y]; - v_w[2] = SDP_Table[256 - res_y]; - v_w[3] = SDP_Table[512 - res_y]; + s_result += a_result * v_w[i]; + } + s_result >>= 16; + return (uint8_t)(s_result < 0 ? 0 : s_result > 255 ? 255 : s_result); } -FXDIB_Format _GetTransformedFormat(const CFX_DIBSource* pDrc) -{ - FXDIB_Format format = pDrc->GetFormat(); - if (pDrc->IsAlphaMask()) { - format = FXDIB_8bppMask; - } else if (format >= 1025) { - format = FXDIB_Cmyka; - } else if (format <= 32 || format == FXDIB_Argb) { - format = FXDIB_Argb; - } else { - format = FXDIB_Rgba; +void _bicubic_get_pos_weight(int pos_pixel[], + int u_w[], + int v_w[], + int src_col_l, + int src_row_l, + int res_x, + int res_y, + int stretch_width, + int stretch_height) { + pos_pixel[0] = src_col_l - 1; + pos_pixel[1] = src_col_l; + pos_pixel[2] = src_col_l + 1; + pos_pixel[3] = src_col_l + 2; + pos_pixel[4] = src_row_l - 1; + pos_pixel[5] = src_row_l; + pos_pixel[6] = src_row_l + 1; + pos_pixel[7] = src_row_l + 2; + for (int i = 0; i < 4; i++) { + if (pos_pixel[i] < 0) { + pos_pixel[i] = 0; } - return format; -} -FX_BOOL CFX_ImageTransformer::Continue(IFX_Pause* pPause) -{ - if (m_Status == 1) { - if (m_Stretcher.Continue(pPause)) { - return TRUE; - } - if (m_Storer.GetBitmap()) { - m_Storer.Replace(m_Storer.GetBitmap()->SwapXY(m_pMatrix->c > 0, m_pMatrix->b < 0)); - } - return FALSE; + if (pos_pixel[i] >= stretch_width) { + pos_pixel[i] = stretch_width - 1; } - if (m_Status == 2) { - return m_Stretcher.Continue(pPause); + if (pos_pixel[i + 4] < 0) { + pos_pixel[i + 4] = 0; } - if (m_Status != 3) { - return FALSE; + if (pos_pixel[i + 4] >= stretch_height) { + pos_pixel[i + 4] = stretch_height - 1; } + } + u_w[0] = SDP_Table[256 + res_x]; + u_w[1] = SDP_Table[res_x]; + u_w[2] = SDP_Table[256 - res_x]; + u_w[3] = SDP_Table[512 - res_x]; + v_w[0] = SDP_Table[256 + res_y]; + v_w[1] = SDP_Table[res_y]; + v_w[2] = SDP_Table[256 - res_y]; + v_w[3] = SDP_Table[512 - res_y]; +} +FXDIB_Format _GetTransformedFormat(const CFX_DIBSource* pDrc) { + FXDIB_Format format = pDrc->GetFormat(); + if (pDrc->IsAlphaMask()) { + format = FXDIB_8bppMask; + } else if (format >= 1025) { + format = FXDIB_Cmyka; + } else if (format <= 32 || format == FXDIB_Argb) { + format = FXDIB_Argb; + } else { + format = FXDIB_Rgba; + } + return format; +} +FX_BOOL CFX_ImageTransformer::Continue(IFX_Pause* pPause) { + if (m_Status == 1) { if (m_Stretcher.Continue(pPause)) { - return TRUE; - } - int stretch_width = m_StretchClip.Width(); - int stretch_height = m_StretchClip.Height(); - if (m_Storer.GetBitmap() == NULL) { - return FALSE; - } - const uint8_t* stretch_buf = m_Storer.GetBitmap()->GetBuffer(); - const uint8_t* stretch_buf_mask = NULL; - if (m_Storer.GetBitmap()->m_pAlphaMask) { - stretch_buf_mask = m_Storer.GetBitmap()->m_pAlphaMask->GetBuffer(); + return TRUE; } - int stretch_pitch = m_Storer.GetBitmap()->GetPitch(); - CFX_DIBitmap* pTransformed = new CFX_DIBitmap; - FXDIB_Format transformF = _GetTransformedFormat(m_Stretcher.m_pSource); - if (!pTransformed->Create(m_ResultWidth, m_ResultHeight, transformF)) { - delete pTransformed; - return FALSE; + if (m_Storer.GetBitmap()) { + m_Storer.Replace( + m_Storer.GetBitmap()->SwapXY(m_pMatrix->c > 0, m_pMatrix->b < 0)); } - pTransformed->Clear(0); - if (pTransformed->m_pAlphaMask) { - pTransformed->m_pAlphaMask->Clear(0); + return FALSE; + } + if (m_Status == 2) { + return m_Stretcher.Continue(pPause); + } + if (m_Status != 3) { + return FALSE; + } + if (m_Stretcher.Continue(pPause)) { + return TRUE; + } + int stretch_width = m_StretchClip.Width(); + int stretch_height = m_StretchClip.Height(); + if (m_Storer.GetBitmap() == NULL) { + return FALSE; + } + const uint8_t* stretch_buf = m_Storer.GetBitmap()->GetBuffer(); + const uint8_t* stretch_buf_mask = NULL; + if (m_Storer.GetBitmap()->m_pAlphaMask) { + stretch_buf_mask = m_Storer.GetBitmap()->m_pAlphaMask->GetBuffer(); + } + int stretch_pitch = m_Storer.GetBitmap()->GetPitch(); + CFX_DIBitmap* pTransformed = new CFX_DIBitmap; + FXDIB_Format transformF = _GetTransformedFormat(m_Stretcher.m_pSource); + if (!pTransformed->Create(m_ResultWidth, m_ResultHeight, transformF)) { + delete pTransformed; + return FALSE; + } + pTransformed->Clear(0); + if (pTransformed->m_pAlphaMask) { + pTransformed->m_pAlphaMask->Clear(0); + } + CFX_AffineMatrix result2stretch(1.0f, 0.0f, 0.0f, 1.0f, + (FX_FLOAT)(m_ResultLeft), + (FX_FLOAT)(m_ResultTop)); + result2stretch.Concat(m_dest2stretch); + result2stretch.TranslateI(-m_StretchClip.left, -m_StretchClip.top); + if (stretch_buf_mask == NULL && pTransformed->m_pAlphaMask) { + pTransformed->m_pAlphaMask->Clear(0xff000000); + } else if (pTransformed->m_pAlphaMask) { + int stretch_pitch_mask = m_Storer.GetBitmap()->m_pAlphaMask->GetPitch(); + if (!(m_Flags & FXDIB_DOWNSAMPLE) && !(m_Flags & FXDIB_BICUBIC_INTERPOL)) { + CFX_BilinearMatrix result2stretch_fix(result2stretch, 8); + for (int row = 0; row < m_ResultHeight; row++) { + uint8_t* dest_pos_mask = + (uint8_t*)pTransformed->m_pAlphaMask->GetScanline(row); + for (int col = 0; col < m_ResultWidth; col++) { + int src_col_l, src_row_l, res_x, res_y; + result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, + res_y); + if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && + src_row_l <= stretch_height) { + if (src_col_l == stretch_width) { + src_col_l--; + } + if (src_row_l == stretch_height) { + src_row_l--; + } + int src_col_r = src_col_l + 1; + int src_row_r = src_row_l + 1; + if (src_col_r == stretch_width) { + src_col_r--; + } + if (src_row_r == stretch_height) { + src_row_r--; + } + int row_offset_l = src_row_l * stretch_pitch_mask; + int row_offset_r = src_row_r * stretch_pitch_mask; + *dest_pos_mask = + _bilinear_interpol(stretch_buf_mask, row_offset_l, row_offset_r, + src_col_l, src_col_r, res_x, res_y, 1, 0); + } + dest_pos_mask++; + } + } + } else if (m_Flags & FXDIB_BICUBIC_INTERPOL) { + CFX_BilinearMatrix result2stretch_fix(result2stretch, 8); + for (int row = 0; row < m_ResultHeight; row++) { + uint8_t* dest_pos_mask = + (uint8_t*)pTransformed->m_pAlphaMask->GetScanline(row); + for (int col = 0; col < m_ResultWidth; col++) { + int src_col_l, src_row_l, res_x, res_y; + result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, + res_y); + if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && + src_row_l <= stretch_height) { + int pos_pixel[8]; + int u_w[4], v_w[4]; + if (src_col_l == stretch_width) { + src_col_l--; + } + if (src_row_l == stretch_height) { + src_row_l--; + } + _bicubic_get_pos_weight(pos_pixel, u_w, v_w, src_col_l, src_row_l, + res_x, res_y, stretch_width, + stretch_height); + *dest_pos_mask = + _bicubic_interpol(stretch_buf_mask, stretch_pitch_mask, + pos_pixel, u_w, v_w, res_x, res_y, 1, 0); + } + dest_pos_mask++; + } + } + } else { + CPDF_FixedMatrix result2stretch_fix(result2stretch, 8); + for (int row = 0; row < m_ResultHeight; row++) { + uint8_t* dest_pos_mask = + (uint8_t*)pTransformed->m_pAlphaMask->GetScanline(row); + for (int col = 0; col < m_ResultWidth; col++) { + int src_col, src_row; + result2stretch_fix.Transform(col, row, src_col, src_row); + if (src_col >= 0 && src_col <= stretch_width && src_row >= 0 && + src_row <= stretch_height) { + if (src_col == stretch_width) { + src_col--; + } + if (src_row == stretch_height) { + src_row--; + } + *dest_pos_mask = + stretch_buf_mask[src_row * stretch_pitch_mask + src_col]; + } + dest_pos_mask++; + } + } } - CFX_AffineMatrix result2stretch(1.0f, 0.0f, 0.0f, 1.0f, (FX_FLOAT)(m_ResultLeft), (FX_FLOAT)(m_ResultTop)); - result2stretch.Concat(m_dest2stretch); - result2stretch.TranslateI(-m_StretchClip.left, -m_StretchClip.top); - if (stretch_buf_mask == NULL && pTransformed->m_pAlphaMask) { - pTransformed->m_pAlphaMask->Clear(0xff000000); - } else if (pTransformed->m_pAlphaMask) { - int stretch_pitch_mask = m_Storer.GetBitmap()->m_pAlphaMask->GetPitch(); - if (!(m_Flags & FXDIB_DOWNSAMPLE) && !(m_Flags & FXDIB_BICUBIC_INTERPOL)) { - CFX_BilinearMatrix result2stretch_fix(result2stretch, 8); - for (int row = 0; row < m_ResultHeight; row ++) { - uint8_t* dest_pos_mask = (uint8_t*)pTransformed->m_pAlphaMask->GetScanline(row); - for (int col = 0; col < m_ResultWidth; col ++) { - int src_col_l, src_row_l, res_x, res_y; - result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, res_y); - if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && src_row_l <= stretch_height) { - if (src_col_l == stretch_width) { - src_col_l--; - } - if (src_row_l == stretch_height) { - src_row_l--; - } - int src_col_r = src_col_l + 1; - int src_row_r = src_row_l + 1; - if (src_col_r == stretch_width) { - src_col_r--; - } - if (src_row_r == stretch_height) { - src_row_r--; - } - int row_offset_l = src_row_l * stretch_pitch_mask; - int row_offset_r = src_row_r * stretch_pitch_mask; - *dest_pos_mask = _bilinear_interpol(stretch_buf_mask, row_offset_l, row_offset_r, src_col_l, src_col_r, res_x, res_y, 1, 0); - } - dest_pos_mask++; - } + } + if (m_Storer.GetBitmap()->IsAlphaMask()) { + if (!(m_Flags & FXDIB_DOWNSAMPLE) && !(m_Flags & FXDIB_BICUBIC_INTERPOL)) { + CFX_BilinearMatrix result2stretch_fix(result2stretch, 8); + for (int row = 0; row < m_ResultHeight; row++) { + uint8_t* dest_scan = (uint8_t*)pTransformed->GetScanline(row); + for (int col = 0; col < m_ResultWidth; col++) { + int src_col_l, src_row_l, res_x, res_y; + result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, + res_y); + if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && + src_row_l <= stretch_height) { + if (src_col_l == stretch_width) { + src_col_l--; } - } else if (m_Flags & FXDIB_BICUBIC_INTERPOL) { - CFX_BilinearMatrix result2stretch_fix(result2stretch, 8); - for (int row = 0; row < m_ResultHeight; row ++) { - uint8_t* dest_pos_mask = (uint8_t*)pTransformed->m_pAlphaMask->GetScanline(row); - for (int col = 0; col < m_ResultWidth; col ++) { - int src_col_l, src_row_l, res_x, res_y; - result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, res_y); - if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && src_row_l <= stretch_height) { - int pos_pixel[8]; - int u_w[4], v_w[4]; - if (src_col_l == stretch_width) { - src_col_l--; - } - if (src_row_l == stretch_height) { - src_row_l--; - } - _bicubic_get_pos_weight(pos_pixel, u_w, v_w, src_col_l, src_row_l, res_x, res_y, stretch_width, stretch_height); - *dest_pos_mask = _bicubic_interpol(stretch_buf_mask, stretch_pitch_mask, pos_pixel, u_w, v_w, res_x, res_y, 1, 0); - } - dest_pos_mask++; - } + if (src_row_l == stretch_height) { + src_row_l--; } - } else { - CPDF_FixedMatrix result2stretch_fix(result2stretch, 8); - for (int row = 0; row < m_ResultHeight; row ++) { - uint8_t* dest_pos_mask = (uint8_t*)pTransformed->m_pAlphaMask->GetScanline(row); - for (int col = 0; col < m_ResultWidth; col ++) { - int src_col, src_row; - result2stretch_fix.Transform(col, row, src_col, src_row); - if (src_col >= 0 && src_col <= stretch_width && src_row >= 0 && src_row <= stretch_height) { - if (src_col == stretch_width) { - src_col --; - } - if (src_row == stretch_height) { - src_row --; - } - *dest_pos_mask = stretch_buf_mask[src_row * stretch_pitch_mask + src_col]; - } - dest_pos_mask++; - } + int src_col_r = src_col_l + 1; + int src_row_r = src_row_l + 1; + if (src_col_r == stretch_width) { + src_col_r--; + } + if (src_row_r == stretch_height) { + src_row_r--; + } + int row_offset_l = src_row_l * stretch_pitch; + int row_offset_r = src_row_r * stretch_pitch; + *dest_scan = + _bilinear_interpol(stretch_buf, row_offset_l, row_offset_r, + src_col_l, src_col_r, res_x, res_y, 1, 0); + } + dest_scan++; + } + } + } else if (m_Flags & FXDIB_BICUBIC_INTERPOL) { + CFX_BilinearMatrix result2stretch_fix(result2stretch, 8); + for (int row = 0; row < m_ResultHeight; row++) { + uint8_t* dest_scan = (uint8_t*)pTransformed->GetScanline(row); + for (int col = 0; col < m_ResultWidth; col++) { + int src_col_l, src_row_l, res_x, res_y; + result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, + res_y); + if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && + src_row_l <= stretch_height) { + int pos_pixel[8]; + int u_w[4], v_w[4]; + if (src_col_l == stretch_width) { + src_col_l--; + } + if (src_row_l == stretch_height) { + src_row_l--; } + _bicubic_get_pos_weight(pos_pixel, u_w, v_w, src_col_l, src_row_l, + res_x, res_y, stretch_width, + stretch_height); + *dest_scan = + _bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, u_w, + v_w, res_x, res_y, 1, 0); + } + dest_scan++; } + } + } else { + CPDF_FixedMatrix result2stretch_fix(result2stretch, 8); + for (int row = 0; row < m_ResultHeight; row++) { + uint8_t* dest_scan = (uint8_t*)pTransformed->GetScanline(row); + for (int col = 0; col < m_ResultWidth; col++) { + int src_col, src_row; + result2stretch_fix.Transform(col, row, src_col, src_row); + if (src_col >= 0 && src_col <= stretch_width && src_row >= 0 && + src_row <= stretch_height) { + if (src_col == stretch_width) { + src_col--; + } + if (src_row == stretch_height) { + src_row--; + } + const uint8_t* src_pixel = + stretch_buf + stretch_pitch * src_row + src_col; + *dest_scan = *src_pixel; + } + dest_scan++; + } + } } - if (m_Storer.GetBitmap()->IsAlphaMask()) { - if (!(m_Flags & FXDIB_DOWNSAMPLE) && !(m_Flags & FXDIB_BICUBIC_INTERPOL)) { - CFX_BilinearMatrix result2stretch_fix(result2stretch, 8); - for (int row = 0; row < m_ResultHeight; row ++) { - uint8_t* dest_scan = (uint8_t*)pTransformed->GetScanline(row); - for (int col = 0; col < m_ResultWidth; col ++) { - int src_col_l, src_row_l, res_x, res_y; - result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, res_y); - if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && src_row_l <= stretch_height) { - if (src_col_l == stretch_width) { - src_col_l--; - } - if (src_row_l == stretch_height) { - src_row_l--; - } - int src_col_r = src_col_l + 1; - int src_row_r = src_row_l + 1; - if (src_col_r == stretch_width) { - src_col_r--; - } - if (src_row_r == stretch_height) { - src_row_r--; - } - int row_offset_l = src_row_l * stretch_pitch; - int row_offset_r = src_row_r * stretch_pitch; - *dest_scan = _bilinear_interpol(stretch_buf, row_offset_l, row_offset_r, src_col_l, src_col_r, res_x, res_y, 1, 0); - } - dest_scan ++; - } + } else { + int Bpp = m_Storer.GetBitmap()->GetBPP() / 8; + int destBpp = pTransformed->GetBPP() / 8; + if (Bpp == 1) { + FX_DWORD argb[256]; + FX_ARGB* pPal = m_Storer.GetBitmap()->GetPalette(); + if (pPal) { + for (int i = 0; i < 256; i++) { + argb[i] = pPal[i]; + } + } else { + if (m_Storer.GetBitmap()->IsCmykImage()) + for (int i = 0; i < 256; i++) { + argb[i] = 255 - i; + } + else + for (int i = 0; i < 256; i++) { + argb[i] = 0xff000000 | (i * 0x010101); + } + } + if (!(m_Flags & FXDIB_DOWNSAMPLE) && + !(m_Flags & FXDIB_BICUBIC_INTERPOL)) { + CFX_BilinearMatrix result2stretch_fix(result2stretch, 8); + for (int row = 0; row < m_ResultHeight; row++) { + uint8_t* dest_pos = (uint8_t*)pTransformed->GetScanline(row); + for (int col = 0; col < m_ResultWidth; col++) { + int src_col_l, src_row_l, res_x, res_y; + result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, + res_y); + if (src_col_l >= 0 && src_col_l <= stretch_width && + src_row_l >= 0 && src_row_l <= stretch_height) { + if (src_col_l == stretch_width) { + src_col_l--; + } + if (src_row_l == stretch_height) { + src_row_l--; + } + int src_col_r = src_col_l + 1; + int src_row_r = src_row_l + 1; + if (src_col_r == stretch_width) { + src_col_r--; + } + if (src_row_r == stretch_height) { + src_row_r--; + } + int row_offset_l = src_row_l * stretch_pitch; + int row_offset_r = src_row_r * stretch_pitch; + FX_DWORD r_bgra_cmyk = argb[_bilinear_interpol( + stretch_buf, row_offset_l, row_offset_r, src_col_l, src_col_r, + res_x, res_y, 1, 0)]; + if (transformF == FXDIB_Rgba) { + dest_pos[0] = (uint8_t)(r_bgra_cmyk >> 24); + dest_pos[1] = (uint8_t)(r_bgra_cmyk >> 16); + dest_pos[2] = (uint8_t)(r_bgra_cmyk >> 8); + } else { + *(FX_DWORD*)dest_pos = r_bgra_cmyk; + } } - } else if (m_Flags & FXDIB_BICUBIC_INTERPOL) { - CFX_BilinearMatrix result2stretch_fix(result2stretch, 8); - for (int row = 0; row < m_ResultHeight; row ++) { - uint8_t* dest_scan = (uint8_t*)pTransformed->GetScanline(row); - for (int col = 0; col < m_ResultWidth; col ++) { - int src_col_l, src_row_l, res_x, res_y; - result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, res_y); - if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && src_row_l <= stretch_height) { - int pos_pixel[8]; - int u_w[4], v_w[4]; - if (src_col_l == stretch_width) { - src_col_l--; - } - if (src_row_l == stretch_height) { - src_row_l--; - } - _bicubic_get_pos_weight(pos_pixel, u_w, v_w, src_col_l, src_row_l, res_x, res_y, stretch_width, stretch_height); - *dest_scan = _bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, u_w, v_w, res_x, res_y, 1, 0); - } - dest_scan ++; - } + dest_pos += destBpp; + } + } + } else if (m_Flags & FXDIB_BICUBIC_INTERPOL) { + CFX_BilinearMatrix result2stretch_fix(result2stretch, 8); + for (int row = 0; row < m_ResultHeight; row++) { + uint8_t* dest_pos = (uint8_t*)pTransformed->GetScanline(row); + for (int col = 0; col < m_ResultWidth; col++) { + int src_col_l, src_row_l, res_x, res_y; + result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, + res_y); + if (src_col_l >= 0 && src_col_l <= stretch_width && + src_row_l >= 0 && src_row_l <= stretch_height) { + int pos_pixel[8]; + int u_w[4], v_w[4]; + if (src_col_l == stretch_width) { + src_col_l--; + } + if (src_row_l == stretch_height) { + src_row_l--; + } + _bicubic_get_pos_weight(pos_pixel, u_w, v_w, src_col_l, src_row_l, + res_x, res_y, stretch_width, + stretch_height); + FX_DWORD r_bgra_cmyk = + argb[_bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, + u_w, v_w, res_x, res_y, 1, 0)]; + if (transformF == FXDIB_Rgba) { + dest_pos[0] = (uint8_t)(r_bgra_cmyk >> 24); + dest_pos[1] = (uint8_t)(r_bgra_cmyk >> 16); + dest_pos[2] = (uint8_t)(r_bgra_cmyk >> 8); + } else { + *(FX_DWORD*)dest_pos = r_bgra_cmyk; + } } - } else { - CPDF_FixedMatrix result2stretch_fix(result2stretch, 8); - for (int row = 0; row < m_ResultHeight; row ++) { - uint8_t* dest_scan = (uint8_t*)pTransformed->GetScanline(row); - for (int col = 0; col < m_ResultWidth; col ++) { - int src_col, src_row; - result2stretch_fix.Transform(col, row, src_col, src_row); - if (src_col >= 0 && src_col <= stretch_width && src_row >= 0 && src_row <= stretch_height) { - if (src_col == stretch_width) { - src_col --; - } - if (src_row == stretch_height) { - src_row --; - } - const uint8_t* src_pixel = stretch_buf + stretch_pitch * src_row + src_col; - *dest_scan = *src_pixel; - } - dest_scan ++; - } + dest_pos += destBpp; + } + } + } else { + CPDF_FixedMatrix result2stretch_fix(result2stretch, 8); + for (int row = 0; row < m_ResultHeight; row++) { + uint8_t* dest_pos = (uint8_t*)pTransformed->GetScanline(row); + for (int col = 0; col < m_ResultWidth; col++) { + int src_col, src_row; + result2stretch_fix.Transform(col, row, src_col, src_row); + if (src_col >= 0 && src_col <= stretch_width && src_row >= 0 && + src_row <= stretch_height) { + if (src_col == stretch_width) { + src_col--; + } + if (src_row == stretch_height) { + src_row--; + } + FX_DWORD r_bgra_cmyk = + argb[stretch_buf[src_row * stretch_pitch + src_col]]; + if (transformF == FXDIB_Rgba) { + dest_pos[0] = (uint8_t)(r_bgra_cmyk >> 24); + dest_pos[1] = (uint8_t)(r_bgra_cmyk >> 16); + dest_pos[2] = (uint8_t)(r_bgra_cmyk >> 8); + } else { + *(FX_DWORD*)dest_pos = r_bgra_cmyk; + } } + dest_pos += destBpp; + } } + } } else { - int Bpp = m_Storer.GetBitmap()->GetBPP() / 8; - int destBpp = pTransformed->GetBPP() / 8; - if (Bpp == 1) { - FX_DWORD argb[256]; - FX_ARGB* pPal = m_Storer.GetBitmap()->GetPalette(); - if (pPal) { - for (int i = 0; i < 256; i ++) { - argb[i] = pPal[i]; + FX_BOOL bHasAlpha = m_Storer.GetBitmap()->HasAlpha(); + int destBpp = pTransformed->GetBPP() / 8; + if (!(m_Flags & FXDIB_DOWNSAMPLE) && + !(m_Flags & FXDIB_BICUBIC_INTERPOL)) { + CFX_BilinearMatrix result2stretch_fix(result2stretch, 8); + for (int row = 0; row < m_ResultHeight; row++) { + uint8_t* dest_pos = (uint8_t*)pTransformed->GetScanline(row); + for (int col = 0; col < m_ResultWidth; col++) { + int src_col_l, src_row_l, res_x, res_y, r_pos_k_r = 0; + result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, + res_y); + if (src_col_l >= 0 && src_col_l <= stretch_width && + src_row_l >= 0 && src_row_l <= stretch_height) { + if (src_col_l == stretch_width) { + src_col_l--; + } + if (src_row_l == stretch_height) { + src_row_l--; + } + int src_col_r = src_col_l + 1; + int src_row_r = src_row_l + 1; + if (src_col_r == stretch_width) { + src_col_r--; + } + if (src_row_r == stretch_height) { + src_row_r--; + } + int row_offset_l = src_row_l * stretch_pitch; + int row_offset_r = src_row_r * stretch_pitch; + uint8_t r_pos_red_y_r = _bilinear_interpol( + stretch_buf, row_offset_l, row_offset_r, src_col_l, src_col_r, + res_x, res_y, Bpp, 2); + uint8_t r_pos_green_m_r = _bilinear_interpol( + stretch_buf, row_offset_l, row_offset_r, src_col_l, src_col_r, + res_x, res_y, Bpp, 1); + uint8_t r_pos_blue_c_r = _bilinear_interpol( + stretch_buf, row_offset_l, row_offset_r, src_col_l, src_col_r, + res_x, res_y, Bpp, 0); + if (bHasAlpha) { + if (transformF != FXDIB_Argb) { + if (transformF == FXDIB_Rgba) { + dest_pos[0] = r_pos_blue_c_r; + dest_pos[1] = r_pos_green_m_r; + dest_pos[2] = r_pos_red_y_r; + } else { + r_pos_k_r = _bilinear_interpol( + stretch_buf, row_offset_l, row_offset_r, src_col_l, + src_col_r, res_x, res_y, Bpp, 3); + *(FX_DWORD*)dest_pos = + FXCMYK_TODIB(CmykEncode(r_pos_blue_c_r, r_pos_green_m_r, + r_pos_red_y_r, r_pos_k_r)); + } + } else { + uint8_t r_pos_a_r = _bilinear_interpol( + stretch_buf, row_offset_l, row_offset_r, src_col_l, + src_col_r, res_x, res_y, Bpp, 3); + *(FX_DWORD*)dest_pos = FXARGB_TODIB( + FXARGB_MAKE(r_pos_a_r, r_pos_red_y_r, r_pos_green_m_r, + r_pos_blue_c_r)); } - } else { - if (m_Storer.GetBitmap()->IsCmykImage()) - for (int i = 0; i < 256; i ++) { - argb[i] = 255 - i; - } - else - for (int i = 0; i < 256; i ++) { - argb[i] = 0xff000000 | (i * 0x010101); - } - } - if (!(m_Flags & FXDIB_DOWNSAMPLE) && !(m_Flags & FXDIB_BICUBIC_INTERPOL)) { - CFX_BilinearMatrix result2stretch_fix(result2stretch, 8); - for (int row = 0; row < m_ResultHeight; row ++) { - uint8_t* dest_pos = (uint8_t*)pTransformed->GetScanline(row); - for (int col = 0; col < m_ResultWidth; col ++) { - int src_col_l, src_row_l, res_x, res_y; - result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, res_y); - if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && src_row_l <= stretch_height) { - if (src_col_l == stretch_width) { - src_col_l--; - } - if (src_row_l == stretch_height) { - src_row_l--; - } - int src_col_r = src_col_l + 1; - int src_row_r = src_row_l + 1; - if (src_col_r == stretch_width) { - src_col_r--; - } - if (src_row_r == stretch_height) { - src_row_r--; - } - int row_offset_l = src_row_l * stretch_pitch; - int row_offset_r = src_row_r * stretch_pitch; - FX_DWORD r_bgra_cmyk = argb[_bilinear_interpol(stretch_buf, row_offset_l, row_offset_r, src_col_l, src_col_r, res_x, res_y, 1, 0)]; - if (transformF == FXDIB_Rgba) { - dest_pos[0] = (uint8_t)(r_bgra_cmyk >> 24); - dest_pos[1] = (uint8_t)(r_bgra_cmyk >> 16); - dest_pos[2] = (uint8_t)(r_bgra_cmyk >> 8); - } else { - *(FX_DWORD*)dest_pos = r_bgra_cmyk; - } - } - dest_pos += destBpp; - } + } else { + r_pos_k_r = 0xff; + if (transformF == FXDIB_Cmyka) { + r_pos_k_r = _bilinear_interpol( + stretch_buf, row_offset_l, row_offset_r, src_col_l, + src_col_r, res_x, res_y, Bpp, 3); + *(FX_DWORD*)dest_pos = + FXCMYK_TODIB(CmykEncode(r_pos_blue_c_r, r_pos_green_m_r, + r_pos_red_y_r, r_pos_k_r)); + } else { + *(FX_DWORD*)dest_pos = FXARGB_TODIB( + FXARGB_MAKE(r_pos_k_r, r_pos_red_y_r, r_pos_green_m_r, + r_pos_blue_c_r)); } - } else if (m_Flags & FXDIB_BICUBIC_INTERPOL) { - CFX_BilinearMatrix result2stretch_fix(result2stretch, 8); - for (int row = 0; row < m_ResultHeight; row ++) { - uint8_t* dest_pos = (uint8_t*)pTransformed->GetScanline(row); - for (int col = 0; col < m_ResultWidth; col ++) { - int src_col_l, src_row_l, res_x, res_y; - result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, res_y); - if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && src_row_l <= stretch_height) { - int pos_pixel[8]; - int u_w[4], v_w[4]; - if (src_col_l == stretch_width) { - src_col_l--; - } - if (src_row_l == stretch_height) { - src_row_l--; - } - _bicubic_get_pos_weight(pos_pixel, u_w, v_w, src_col_l, src_row_l, res_x, res_y, stretch_width, stretch_height); - FX_DWORD r_bgra_cmyk = argb[_bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, u_w, v_w, res_x, res_y, 1, 0)]; - if (transformF == FXDIB_Rgba) { - dest_pos[0] = (uint8_t)(r_bgra_cmyk >> 24); - dest_pos[1] = (uint8_t)(r_bgra_cmyk >> 16); - dest_pos[2] = (uint8_t)(r_bgra_cmyk >> 8); - } else { - *(FX_DWORD*)dest_pos = r_bgra_cmyk; - } - } - dest_pos += destBpp; - } + } + } + dest_pos += destBpp; + } + } + } else if (m_Flags & FXDIB_BICUBIC_INTERPOL) { + CFX_BilinearMatrix result2stretch_fix(result2stretch, 8); + for (int row = 0; row < m_ResultHeight; row++) { + uint8_t* dest_pos = (uint8_t*)pTransformed->GetScanline(row); + for (int col = 0; col < m_ResultWidth; col++) { + int src_col_l, src_row_l, res_x, res_y, r_pos_k_r = 0; + result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, + res_y); + if (src_col_l >= 0 && src_col_l <= stretch_width && + src_row_l >= 0 && src_row_l <= stretch_height) { + int pos_pixel[8]; + int u_w[4], v_w[4]; + if (src_col_l == stretch_width) { + src_col_l--; + } + if (src_row_l == stretch_height) { + src_row_l--; + } + _bicubic_get_pos_weight(pos_pixel, u_w, v_w, src_col_l, src_row_l, + res_x, res_y, stretch_width, + stretch_height); + uint8_t r_pos_red_y_r = + _bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, u_w, + v_w, res_x, res_y, Bpp, 2); + uint8_t r_pos_green_m_r = + _bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, u_w, + v_w, res_x, res_y, Bpp, 1); + uint8_t r_pos_blue_c_r = + _bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, u_w, + v_w, res_x, res_y, Bpp, 0); + if (bHasAlpha) { + if (transformF != FXDIB_Argb) { + if (transformF == FXDIB_Rgba) { + dest_pos[0] = r_pos_blue_c_r; + dest_pos[1] = r_pos_green_m_r; + dest_pos[2] = r_pos_red_y_r; + } else { + r_pos_k_r = + _bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, + u_w, v_w, res_x, res_y, Bpp, 3); + *(FX_DWORD*)dest_pos = + FXCMYK_TODIB(CmykEncode(r_pos_blue_c_r, r_pos_green_m_r, + r_pos_red_y_r, r_pos_k_r)); + } + } else { + uint8_t r_pos_a_r = + _bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, + u_w, v_w, res_x, res_y, Bpp, 3); + *(FX_DWORD*)dest_pos = FXARGB_TODIB( + FXARGB_MAKE(r_pos_a_r, r_pos_red_y_r, r_pos_green_m_r, + r_pos_blue_c_r)); } - } else { - CPDF_FixedMatrix result2stretch_fix(result2stretch, 8); - for (int row = 0; row < m_ResultHeight; row ++) { - uint8_t* dest_pos = (uint8_t*)pTransformed->GetScanline(row); - for (int col = 0; col < m_ResultWidth; col ++) { - int src_col, src_row; - result2stretch_fix.Transform(col, row, src_col, src_row); - if (src_col >= 0 && src_col <= stretch_width && src_row >= 0 && src_row <= stretch_height) { - if (src_col == stretch_width) { - src_col --; - } - if (src_row == stretch_height) { - src_row --; - } - FX_DWORD r_bgra_cmyk = argb[stretch_buf[src_row * stretch_pitch + src_col]]; - if (transformF == FXDIB_Rgba) { - dest_pos[0] = (uint8_t)(r_bgra_cmyk >> 24); - dest_pos[1] = (uint8_t)(r_bgra_cmyk >> 16); - dest_pos[2] = (uint8_t)(r_bgra_cmyk >> 8); - } else { - *(FX_DWORD*)dest_pos = r_bgra_cmyk; - } - } - dest_pos += destBpp; - } + } else { + r_pos_k_r = 0xff; + if (transformF == FXDIB_Cmyka) { + r_pos_k_r = + _bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, + u_w, v_w, res_x, res_y, Bpp, 3); + *(FX_DWORD*)dest_pos = + FXCMYK_TODIB(CmykEncode(r_pos_blue_c_r, r_pos_green_m_r, + r_pos_red_y_r, r_pos_k_r)); + } else { + *(FX_DWORD*)dest_pos = FXARGB_TODIB( + FXARGB_MAKE(r_pos_k_r, r_pos_red_y_r, r_pos_green_m_r, + r_pos_blue_c_r)); } + } } - } else { - FX_BOOL bHasAlpha = m_Storer.GetBitmap()->HasAlpha(); - int destBpp = pTransformed->GetBPP() / 8; - if (!(m_Flags & FXDIB_DOWNSAMPLE) && !(m_Flags & FXDIB_BICUBIC_INTERPOL)) { - CFX_BilinearMatrix result2stretch_fix(result2stretch, 8); - for (int row = 0; row < m_ResultHeight; row ++) { - uint8_t* dest_pos = (uint8_t*)pTransformed->GetScanline(row); - for (int col = 0; col < m_ResultWidth; col ++) { - int src_col_l, src_row_l, res_x, res_y, r_pos_k_r = 0; - result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, res_y); - if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && src_row_l <= stretch_height) { - if (src_col_l == stretch_width) { - src_col_l--; - } - if (src_row_l == stretch_height) { - src_row_l--; - } - int src_col_r = src_col_l + 1; - int src_row_r = src_row_l + 1; - if (src_col_r == stretch_width) { - src_col_r--; - } - if (src_row_r == stretch_height) { - src_row_r--; - } - int row_offset_l = src_row_l * stretch_pitch; - int row_offset_r = src_row_r * stretch_pitch; - uint8_t r_pos_red_y_r = _bilinear_interpol(stretch_buf, row_offset_l, row_offset_r, src_col_l, src_col_r, res_x, res_y, Bpp, 2); - uint8_t r_pos_green_m_r = _bilinear_interpol(stretch_buf, row_offset_l, row_offset_r, src_col_l, src_col_r, res_x, res_y, Bpp, 1); - uint8_t r_pos_blue_c_r = _bilinear_interpol(stretch_buf, row_offset_l, row_offset_r, src_col_l, src_col_r, res_x, res_y, Bpp, 0); - if (bHasAlpha) { - if (transformF != FXDIB_Argb) { - if (transformF == FXDIB_Rgba) { - dest_pos[0] = r_pos_blue_c_r; - dest_pos[1] = r_pos_green_m_r; - dest_pos[2] = r_pos_red_y_r; - } else { - r_pos_k_r = _bilinear_interpol(stretch_buf, row_offset_l, row_offset_r, src_col_l, src_col_r, res_x, res_y, Bpp, 3); - *(FX_DWORD*)dest_pos = FXCMYK_TODIB(CmykEncode(r_pos_blue_c_r, r_pos_green_m_r, r_pos_red_y_r, r_pos_k_r)); - } - } else { - uint8_t r_pos_a_r = _bilinear_interpol(stretch_buf, row_offset_l, row_offset_r, src_col_l, src_col_r, res_x, res_y, Bpp, 3); - *(FX_DWORD*)dest_pos = FXARGB_TODIB(FXARGB_MAKE(r_pos_a_r, r_pos_red_y_r, r_pos_green_m_r, r_pos_blue_c_r)); - } - } else { - r_pos_k_r = 0xff; - if (transformF == FXDIB_Cmyka) { - r_pos_k_r = _bilinear_interpol(stretch_buf, row_offset_l, row_offset_r, src_col_l, src_col_r, res_x, res_y, Bpp, 3); - *(FX_DWORD*)dest_pos = FXCMYK_TODIB(CmykEncode(r_pos_blue_c_r, r_pos_green_m_r, r_pos_red_y_r, r_pos_k_r)); - } else { - *(FX_DWORD*)dest_pos = FXARGB_TODIB(FXARGB_MAKE(r_pos_k_r, r_pos_red_y_r, r_pos_green_m_r, r_pos_blue_c_r)); - } - } - } - dest_pos += destBpp; - } - } - } else if (m_Flags & FXDIB_BICUBIC_INTERPOL) { - CFX_BilinearMatrix result2stretch_fix(result2stretch, 8); - for (int row = 0; row < m_ResultHeight; row ++) { - uint8_t* dest_pos = (uint8_t*)pTransformed->GetScanline(row); - for (int col = 0; col < m_ResultWidth; col ++) { - int src_col_l, src_row_l, res_x, res_y, r_pos_k_r = 0; - result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, res_y); - if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && src_row_l <= stretch_height) { - int pos_pixel[8]; - int u_w[4], v_w[4]; - if (src_col_l == stretch_width) { - src_col_l--; - } - if (src_row_l == stretch_height) { - src_row_l--; - } - _bicubic_get_pos_weight(pos_pixel, u_w, v_w, src_col_l, src_row_l, res_x, res_y, stretch_width, stretch_height); - uint8_t r_pos_red_y_r = _bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, u_w, v_w, res_x, res_y, Bpp, 2); - uint8_t r_pos_green_m_r = _bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, u_w, v_w, res_x, res_y, Bpp, 1); - uint8_t r_pos_blue_c_r = _bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, u_w, v_w, res_x, res_y, Bpp, 0); - if (bHasAlpha) { - if (transformF != FXDIB_Argb) { - if (transformF == FXDIB_Rgba) { - dest_pos[0] = r_pos_blue_c_r; - dest_pos[1] = r_pos_green_m_r; - dest_pos[2] = r_pos_red_y_r; - } else { - r_pos_k_r = _bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, u_w, v_w, res_x, res_y, Bpp, 3); - *(FX_DWORD*)dest_pos = FXCMYK_TODIB(CmykEncode(r_pos_blue_c_r, r_pos_green_m_r, r_pos_red_y_r, r_pos_k_r)); - } - } else { - uint8_t r_pos_a_r = _bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, u_w, v_w, res_x, res_y, Bpp, 3); - *(FX_DWORD*)dest_pos = FXARGB_TODIB(FXARGB_MAKE(r_pos_a_r, r_pos_red_y_r, r_pos_green_m_r, r_pos_blue_c_r)); - } - } else { - r_pos_k_r = 0xff; - if (transformF == FXDIB_Cmyka) { - r_pos_k_r = _bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, u_w, v_w, res_x, res_y, Bpp, 3); - *(FX_DWORD*)dest_pos = FXCMYK_TODIB(CmykEncode(r_pos_blue_c_r, r_pos_green_m_r, r_pos_red_y_r, r_pos_k_r)); - } else { - *(FX_DWORD*)dest_pos = FXARGB_TODIB(FXARGB_MAKE(r_pos_k_r, r_pos_red_y_r, r_pos_green_m_r, r_pos_blue_c_r)); - } - } - } - dest_pos += destBpp; - } + dest_pos += destBpp; + } + } + } else { + CPDF_FixedMatrix result2stretch_fix(result2stretch, 8); + for (int row = 0; row < m_ResultHeight; row++) { + uint8_t* dest_pos = (uint8_t*)pTransformed->GetScanline(row); + for (int col = 0; col < m_ResultWidth; col++) { + int src_col, src_row; + result2stretch_fix.Transform(col, row, src_col, src_row); + if (src_col >= 0 && src_col <= stretch_width && src_row >= 0 && + src_row <= stretch_height) { + if (src_col == stretch_width) { + src_col--; + } + if (src_row == stretch_height) { + src_row--; + } + const uint8_t* src_pos = + stretch_buf + src_row * stretch_pitch + src_col * Bpp; + if (bHasAlpha) { + if (transformF != FXDIB_Argb) { + if (transformF == FXDIB_Rgba) { + dest_pos[0] = src_pos[0]; + dest_pos[1] = src_pos[1]; + dest_pos[2] = src_pos[2]; + } else { + *(FX_DWORD*)dest_pos = FXCMYK_TODIB(CmykEncode( + src_pos[0], src_pos[1], src_pos[2], src_pos[3])); + } + } else { + *(FX_DWORD*)dest_pos = FXARGB_TODIB(FXARGB_MAKE( + src_pos[3], src_pos[2], src_pos[1], src_pos[0])); } - } else { - CPDF_FixedMatrix result2stretch_fix(result2stretch, 8); - for (int row = 0; row < m_ResultHeight; row ++) { - uint8_t* dest_pos = (uint8_t*)pTransformed->GetScanline(row); - for (int col = 0; col < m_ResultWidth; col ++) { - int src_col, src_row; - result2stretch_fix.Transform(col, row, src_col, src_row); - if (src_col >= 0 && src_col <= stretch_width && src_row >= 0 && src_row <= stretch_height) { - if (src_col == stretch_width) { - src_col --; - } - if (src_row == stretch_height) { - src_row --; - } - const uint8_t* src_pos = stretch_buf + src_row * stretch_pitch + src_col * Bpp; - if (bHasAlpha) { - if (transformF != FXDIB_Argb) { - if (transformF == FXDIB_Rgba) { - dest_pos[0] = src_pos[0]; - dest_pos[1] = src_pos[1]; - dest_pos[2] = src_pos[2]; - } else { - *(FX_DWORD*)dest_pos = FXCMYK_TODIB(CmykEncode(src_pos[0], src_pos[1], src_pos[2], src_pos[3])); - } - } else { - *(FX_DWORD*)dest_pos = FXARGB_TODIB(FXARGB_MAKE(src_pos[3], src_pos[2], src_pos[1], src_pos[0])); - } - } else { - if (transformF == FXDIB_Cmyka) { - *(FX_DWORD*)dest_pos = FXCMYK_TODIB(CmykEncode(src_pos[0], src_pos[1], src_pos[2], src_pos[3])); - } else { - *(FX_DWORD*)dest_pos = FXARGB_TODIB(FXARGB_MAKE(0xff, src_pos[2], src_pos[1], src_pos[0])); - } - } - } - dest_pos += destBpp; - } + } else { + if (transformF == FXDIB_Cmyka) { + *(FX_DWORD*)dest_pos = FXCMYK_TODIB(CmykEncode( + src_pos[0], src_pos[1], src_pos[2], src_pos[3])); + } else { + *(FX_DWORD*)dest_pos = FXARGB_TODIB( + FXARGB_MAKE(0xff, src_pos[2], src_pos[1], src_pos[0])); } + } } + dest_pos += destBpp; + } } + } } - m_Storer.Replace(pTransformed); - return FALSE; + } + m_Storer.Replace(pTransformed); + return FALSE; } diff --git a/core/src/fxge/ge/fx_ge.cpp b/core/src/fxge/ge/fx_ge.cpp index 6ba6cf5979..d37ed5c714 100644 --- a/core/src/fxge/ge/fx_ge.cpp +++ b/core/src/fxge/ge/fx_ge.cpp @@ -7,59 +7,51 @@ #include "../../../include/fxge/fx_ge.h" #include "text_int.h" static CFX_GEModule* g_pGEModule = NULL; -CFX_GEModule::CFX_GEModule() -{ - m_pFontCache = NULL; - m_pFontMgr = NULL; - m_FTLibrary = NULL; - m_pCodecModule = NULL; - m_pPlatformData = NULL; -} -CFX_GEModule::~CFX_GEModule() -{ - delete m_pFontCache; - m_pFontCache = NULL; - delete m_pFontMgr; - m_pFontMgr = NULL; - DestroyPlatform(); -} -CFX_GEModule* CFX_GEModule::Get() -{ - return g_pGEModule; -} -void CFX_GEModule::Create() -{ - g_pGEModule = new CFX_GEModule; - g_pGEModule->m_pFontMgr = new CFX_FontMgr; - g_pGEModule->InitPlatform(); - g_pGEModule->SetTextGamma(2.2f); -} -void CFX_GEModule::Use(CFX_GEModule* pModule) -{ - g_pGEModule = pModule; -} -void CFX_GEModule::Destroy() -{ - delete g_pGEModule; - g_pGEModule = NULL; -} -CFX_FontCache* CFX_GEModule::GetFontCache() -{ - if (m_pFontCache == NULL) { - m_pFontCache = new CFX_FontCache(); - } - return m_pFontCache; -} -void CFX_GEModule::SetTextGamma(FX_FLOAT gammaValue) -{ - gammaValue /= 2.2f; - int i = 0; - while (i < 256) { - m_GammaValue[i] = (uint8_t)(FXSYS_pow((FX_FLOAT)i / 255, gammaValue) * 255.0f + 0.5f); - i++; - } -} -const uint8_t* CFX_GEModule::GetTextGammaTable() -{ - return m_GammaValue; +CFX_GEModule::CFX_GEModule() { + m_pFontCache = NULL; + m_pFontMgr = NULL; + m_FTLibrary = NULL; + m_pCodecModule = NULL; + m_pPlatformData = NULL; +} +CFX_GEModule::~CFX_GEModule() { + delete m_pFontCache; + m_pFontCache = NULL; + delete m_pFontMgr; + m_pFontMgr = NULL; + DestroyPlatform(); +} +CFX_GEModule* CFX_GEModule::Get() { + return g_pGEModule; +} +void CFX_GEModule::Create() { + g_pGEModule = new CFX_GEModule; + g_pGEModule->m_pFontMgr = new CFX_FontMgr; + g_pGEModule->InitPlatform(); + g_pGEModule->SetTextGamma(2.2f); +} +void CFX_GEModule::Use(CFX_GEModule* pModule) { + g_pGEModule = pModule; +} +void CFX_GEModule::Destroy() { + delete g_pGEModule; + g_pGEModule = NULL; +} +CFX_FontCache* CFX_GEModule::GetFontCache() { + if (m_pFontCache == NULL) { + m_pFontCache = new CFX_FontCache(); + } + return m_pFontCache; +} +void CFX_GEModule::SetTextGamma(FX_FLOAT gammaValue) { + gammaValue /= 2.2f; + int i = 0; + while (i < 256) { + m_GammaValue[i] = + (uint8_t)(FXSYS_pow((FX_FLOAT)i / 255, gammaValue) * 255.0f + 0.5f); + i++; + } +} +const uint8_t* CFX_GEModule::GetTextGammaTable() { + return m_GammaValue; } diff --git a/core/src/fxge/ge/fx_ge_device.cpp b/core/src/fxge/ge/fx_ge_device.cpp index 0baa99cdc7..7ab399a3bd 100644 --- a/core/src/fxge/ge/fx_ge_device.cpp +++ b/core/src/fxge/ge/fx_ge_device.cpp @@ -5,398 +5,471 @@ // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com #include "../../../include/fxge/fx_ge.h" -CFX_RenderDevice::CFX_RenderDevice() -{ - m_pDeviceDriver = NULL; - m_pBitmap = NULL; +CFX_RenderDevice::CFX_RenderDevice() { + m_pDeviceDriver = NULL; + m_pBitmap = NULL; } -CFX_RenderDevice::~CFX_RenderDevice() -{ - delete m_pDeviceDriver; +CFX_RenderDevice::~CFX_RenderDevice() { + delete m_pDeviceDriver; } -void CFX_RenderDevice::SetDeviceDriver(IFX_RenderDeviceDriver* pDriver) -{ - delete m_pDeviceDriver; - m_pDeviceDriver = pDriver; - InitDeviceInfo(); +void CFX_RenderDevice::SetDeviceDriver(IFX_RenderDeviceDriver* pDriver) { + delete m_pDeviceDriver; + m_pDeviceDriver = pDriver; + InitDeviceInfo(); } -void CFX_RenderDevice::InitDeviceInfo() -{ - ASSERT(m_pDeviceDriver != NULL); - m_Width = m_pDeviceDriver->GetDeviceCaps(FXDC_PIXEL_WIDTH); - m_Height = m_pDeviceDriver->GetDeviceCaps(FXDC_PIXEL_HEIGHT); - m_bpp = m_pDeviceDriver->GetDeviceCaps(FXDC_BITS_PIXEL); - m_RenderCaps = m_pDeviceDriver->GetDeviceCaps(FXDC_RENDER_CAPS); - m_DeviceClass = m_pDeviceDriver->GetDeviceCaps(FXDC_DEVICE_CLASS); - if (!m_pDeviceDriver->GetClipBox(&m_ClipBox)) { - m_ClipBox.left = 0; - m_ClipBox.top = 0; - m_ClipBox.right = m_Width; - m_ClipBox.bottom = m_Height; - } +void CFX_RenderDevice::InitDeviceInfo() { + ASSERT(m_pDeviceDriver != NULL); + m_Width = m_pDeviceDriver->GetDeviceCaps(FXDC_PIXEL_WIDTH); + m_Height = m_pDeviceDriver->GetDeviceCaps(FXDC_PIXEL_HEIGHT); + m_bpp = m_pDeviceDriver->GetDeviceCaps(FXDC_BITS_PIXEL); + m_RenderCaps = m_pDeviceDriver->GetDeviceCaps(FXDC_RENDER_CAPS); + m_DeviceClass = m_pDeviceDriver->GetDeviceCaps(FXDC_DEVICE_CLASS); + if (!m_pDeviceDriver->GetClipBox(&m_ClipBox)) { + m_ClipBox.left = 0; + m_ClipBox.top = 0; + m_ClipBox.right = m_Width; + m_ClipBox.bottom = m_Height; + } } -FX_BOOL CFX_RenderDevice::StartRendering() -{ - return m_pDeviceDriver->StartRendering(); +FX_BOOL CFX_RenderDevice::StartRendering() { + return m_pDeviceDriver->StartRendering(); } -void CFX_RenderDevice::EndRendering() -{ - m_pDeviceDriver->EndRendering(); +void CFX_RenderDevice::EndRendering() { + m_pDeviceDriver->EndRendering(); } -void CFX_RenderDevice::SaveState() -{ - m_pDeviceDriver->SaveState(); +void CFX_RenderDevice::SaveState() { + m_pDeviceDriver->SaveState(); } -void CFX_RenderDevice::RestoreState(FX_BOOL bKeepSaved) -{ - m_pDeviceDriver->RestoreState(bKeepSaved); - UpdateClipBox(); +void CFX_RenderDevice::RestoreState(FX_BOOL bKeepSaved) { + m_pDeviceDriver->RestoreState(bKeepSaved); + UpdateClipBox(); } -int CFX_RenderDevice::GetDeviceCaps(int caps_id) const -{ - return m_pDeviceDriver->GetDeviceCaps(caps_id); +int CFX_RenderDevice::GetDeviceCaps(int caps_id) const { + return m_pDeviceDriver->GetDeviceCaps(caps_id); } -CFX_Matrix CFX_RenderDevice::GetCTM() const -{ - return m_pDeviceDriver->GetCTM(); +CFX_Matrix CFX_RenderDevice::GetCTM() const { + return m_pDeviceDriver->GetCTM(); } -FX_BOOL CFX_RenderDevice::CreateCompatibleBitmap(CFX_DIBitmap* pDIB, int width, int height) const -{ - if (m_RenderCaps & FXRC_CMYK_OUTPUT) { - return pDIB->Create(width, height, m_RenderCaps & FXRC_ALPHA_OUTPUT ? FXDIB_Cmyka : FXDIB_Cmyk); - } - if (m_RenderCaps & FXRC_BYTEMASK_OUTPUT) { - return pDIB->Create(width, height, FXDIB_8bppMask); - } -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - return pDIB->Create(width, height, m_RenderCaps & FXRC_ALPHA_OUTPUT ? FXDIB_Argb : FXDIB_Rgb32); +FX_BOOL CFX_RenderDevice::CreateCompatibleBitmap(CFX_DIBitmap* pDIB, + int width, + int height) const { + if (m_RenderCaps & FXRC_CMYK_OUTPUT) { + return pDIB->Create(width, height, m_RenderCaps & FXRC_ALPHA_OUTPUT + ? FXDIB_Cmyka + : FXDIB_Cmyk); + } + if (m_RenderCaps & FXRC_BYTEMASK_OUTPUT) { + return pDIB->Create(width, height, FXDIB_8bppMask); + } +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + return pDIB->Create(width, height, m_RenderCaps & FXRC_ALPHA_OUTPUT + ? FXDIB_Argb + : FXDIB_Rgb32); #else - return pDIB->Create(width, height, m_RenderCaps & FXRC_ALPHA_OUTPUT ? FXDIB_Argb : FXDIB_Rgb); + return pDIB->Create( + width, height, m_RenderCaps & FXRC_ALPHA_OUTPUT ? FXDIB_Argb : FXDIB_Rgb); #endif } -FX_BOOL CFX_RenderDevice::SetClip_PathFill(const CFX_PathData* pPathData, - const CFX_AffineMatrix* pObject2Device, - int fill_mode - ) -{ - if (!m_pDeviceDriver->SetClip_PathFill(pPathData, pObject2Device, fill_mode)) { - return FALSE; - } - UpdateClipBox(); - return TRUE; +FX_BOOL CFX_RenderDevice::SetClip_PathFill( + const CFX_PathData* pPathData, + const CFX_AffineMatrix* pObject2Device, + int fill_mode) { + if (!m_pDeviceDriver->SetClip_PathFill(pPathData, pObject2Device, + fill_mode)) { + return FALSE; + } + UpdateClipBox(); + return TRUE; } -FX_BOOL CFX_RenderDevice::SetClip_PathStroke(const CFX_PathData* pPathData, - const CFX_AffineMatrix* pObject2Device, - const CFX_GraphStateData* pGraphState - ) -{ - if (!m_pDeviceDriver->SetClip_PathStroke(pPathData, pObject2Device, pGraphState)) { - return FALSE; - } - UpdateClipBox(); - return TRUE; +FX_BOOL CFX_RenderDevice::SetClip_PathStroke( + const CFX_PathData* pPathData, + const CFX_AffineMatrix* pObject2Device, + const CFX_GraphStateData* pGraphState) { + if (!m_pDeviceDriver->SetClip_PathStroke(pPathData, pObject2Device, + pGraphState)) { + return FALSE; + } + UpdateClipBox(); + return TRUE; } -FX_BOOL CFX_RenderDevice::SetClip_Rect(const FX_RECT* pRect) -{ - CFX_PathData path; - path.AppendRect((FX_FLOAT)(pRect->left), (FX_FLOAT)(pRect->bottom), (FX_FLOAT)(pRect->right), (FX_FLOAT)(pRect->top)); - if (!SetClip_PathFill(&path, NULL, FXFILL_WINDING)) { - return FALSE; - } - UpdateClipBox(); - return TRUE; +FX_BOOL CFX_RenderDevice::SetClip_Rect(const FX_RECT* pRect) { + CFX_PathData path; + path.AppendRect((FX_FLOAT)(pRect->left), (FX_FLOAT)(pRect->bottom), + (FX_FLOAT)(pRect->right), (FX_FLOAT)(pRect->top)); + if (!SetClip_PathFill(&path, NULL, FXFILL_WINDING)) { + return FALSE; + } + UpdateClipBox(); + return TRUE; } -void CFX_RenderDevice::UpdateClipBox() -{ - if (m_pDeviceDriver->GetClipBox(&m_ClipBox)) { - return; - } - m_ClipBox.left = 0; - m_ClipBox.top = 0; - m_ClipBox.right = m_Width; - m_ClipBox.bottom = m_Height; +void CFX_RenderDevice::UpdateClipBox() { + if (m_pDeviceDriver->GetClipBox(&m_ClipBox)) { + return; + } + m_ClipBox.left = 0; + m_ClipBox.top = 0; + m_ClipBox.right = m_Width; + m_ClipBox.bottom = m_Height; } FX_BOOL CFX_RenderDevice::DrawPath(const CFX_PathData* pPathData, const CFX_AffineMatrix* pObject2Device, const CFX_GraphStateData* pGraphState, - FX_DWORD fill_color, FX_DWORD stroke_color, int fill_mode, - int alpha_flag, void* pIccTransform, int blend_type) -{ - uint8_t fill_alpha, stroke_alpha; - if (FXGETFLAG_COLORTYPE(alpha_flag)) { - fill_alpha = FXGETFLAG_ALPHA_FILL(alpha_flag); - stroke_alpha = FXGETFLAG_ALPHA_STROKE(alpha_flag); + FX_DWORD fill_color, + FX_DWORD stroke_color, + int fill_mode, + int alpha_flag, + void* pIccTransform, + int blend_type) { + uint8_t fill_alpha, stroke_alpha; + if (FXGETFLAG_COLORTYPE(alpha_flag)) { + fill_alpha = FXGETFLAG_ALPHA_FILL(alpha_flag); + stroke_alpha = FXGETFLAG_ALPHA_STROKE(alpha_flag); + } else { + fill_alpha = FXARGB_A(fill_color); + stroke_alpha = FXARGB_A(stroke_color); + } + if ((fill_mode & 3) == 0) { + fill_alpha = 0; + } + if (pGraphState == NULL) { + stroke_alpha = 0; + } + if (stroke_alpha == 0 && pPathData->GetPointCount() == 2) { + FX_PATHPOINT* pPoints = pPathData->GetPoints(); + FX_FLOAT x1, x2, y1, y2; + if (pObject2Device) { + pObject2Device->Transform(pPoints[0].m_PointX, pPoints[0].m_PointY, x1, + y1); + pObject2Device->Transform(pPoints[1].m_PointX, pPoints[1].m_PointY, x2, + y2); } else { - fill_alpha = FXARGB_A(fill_color); - stroke_alpha = FXARGB_A(stroke_color); - } - if ((fill_mode & 3) == 0) { - fill_alpha = 0; - } - if (pGraphState == NULL) { - stroke_alpha = 0; - } - if (stroke_alpha == 0 && pPathData->GetPointCount() == 2) { - FX_PATHPOINT* pPoints = pPathData->GetPoints(); - FX_FLOAT x1, x2, y1, y2; - if (pObject2Device) { - pObject2Device->Transform(pPoints[0].m_PointX, pPoints[0].m_PointY, x1, y1); - pObject2Device->Transform(pPoints[1].m_PointX, pPoints[1].m_PointY, x2, y2); - } else { - x1 = pPoints[0].m_PointX; - y1 = pPoints[0].m_PointY; - x2 = pPoints[1].m_PointX; - y2 = pPoints[1].m_PointY; - } - DrawCosmeticLine(x1, y1, x2, y2, fill_color, fill_mode, alpha_flag, pIccTransform, blend_type); - return TRUE; + x1 = pPoints[0].m_PointX; + y1 = pPoints[0].m_PointY; + x2 = pPoints[1].m_PointX; + y2 = pPoints[1].m_PointY; } - if ((pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) && stroke_alpha == 0) { - CFX_FloatRect rect_f; - if (!(fill_mode & FXFILL_RECT_AA) && pPathData->IsRect(pObject2Device, &rect_f)) { - FX_RECT rect_i = rect_f.GetOutterRect(); - int width = (int)FXSYS_ceil(rect_f.right - rect_f.left); - if (width < 1) { - width = 1; - if (rect_i.left == rect_i.right) { - rect_i.right ++; - } - } - int height = (int)FXSYS_ceil(rect_f.top - rect_f.bottom); - if (height < 1) { - height = 1; - if (rect_i.bottom == rect_i.top) { - rect_i.bottom ++; - } - } - if (rect_i.Width() >= width + 1) { - if (rect_f.left - (FX_FLOAT)(rect_i.left) > (FX_FLOAT)(rect_i.right) - rect_f.right) { - rect_i.left ++; - } else { - rect_i.right --; - } - } - if (rect_i.Height() >= height + 1) { - if (rect_f.top - (FX_FLOAT)(rect_i.top) > (FX_FLOAT)(rect_i.bottom) - rect_f.bottom) { - rect_i.top ++; - } else { - rect_i.bottom --; - } - } - if (FillRect(&rect_i, fill_color, alpha_flag, pIccTransform, blend_type)) { - return TRUE; - } + DrawCosmeticLine(x1, y1, x2, y2, fill_color, fill_mode, alpha_flag, + pIccTransform, blend_type); + return TRUE; + } + if ((pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) && + stroke_alpha == 0) { + CFX_FloatRect rect_f; + if (!(fill_mode & FXFILL_RECT_AA) && + pPathData->IsRect(pObject2Device, &rect_f)) { + FX_RECT rect_i = rect_f.GetOutterRect(); + int width = (int)FXSYS_ceil(rect_f.right - rect_f.left); + if (width < 1) { + width = 1; + if (rect_i.left == rect_i.right) { + rect_i.right++; } - } - if((fill_mode & 3) && stroke_alpha == 0 && !(fill_mode & FX_FILL_STROKE) && !(fill_mode & FX_FILL_TEXT_MODE)) { - CFX_PathData newPath; - FX_BOOL bThin = FALSE; - if (pPathData->GetZeroAreaPath(newPath, (CFX_Matrix*)pObject2Device, bThin, m_pDeviceDriver->GetDriverType())) { - CFX_GraphStateData graphState; - graphState.m_LineWidth = 0.0f; - FX_DWORD strokecolor = fill_color; - if (bThin) { - if (FXGETFLAG_COLORTYPE(alpha_flag)) { - FXSETFLAG_ALPHA_STROKE(alpha_flag, fill_alpha >> 2); - } else { - strokecolor = (((fill_alpha >> 2) << 24) | (strokecolor & 0x00ffffff)); - } - } - CFX_AffineMatrix* pMatrix = NULL; - if (pObject2Device && !pObject2Device->IsIdentity()) { - pMatrix = (CFX_AffineMatrix*)pObject2Device; - } - int smooth_path = FX_ZEROAREA_FILL; - if (fill_mode & FXFILL_NOPATHSMOOTH) { - smooth_path |= FXFILL_NOPATHSMOOTH; - } - m_pDeviceDriver->DrawPath(&newPath, pMatrix, &graphState, 0, strokecolor, smooth_path, alpha_flag, pIccTransform, blend_type); + } + int height = (int)FXSYS_ceil(rect_f.top - rect_f.bottom); + if (height < 1) { + height = 1; + if (rect_i.bottom == rect_i.top) { + rect_i.bottom++; } - } - if ((fill_mode & 3) && fill_alpha && stroke_alpha < 0xff && (fill_mode & FX_FILL_STROKE)) { - if (!(m_RenderCaps & FXRC_GET_BITS)) { - return FALSE; - } - CFX_FloatRect bbox; - if (pGraphState) { - bbox = pPathData->GetBoundingBox(pGraphState->m_LineWidth, pGraphState->m_MiterLimit); + } + if (rect_i.Width() >= width + 1) { + if (rect_f.left - (FX_FLOAT)(rect_i.left) > + (FX_FLOAT)(rect_i.right) - rect_f.right) { + rect_i.left++; } else { - bbox = pPathData->GetBoundingBox(); - } - if (pObject2Device) { - bbox.Transform(pObject2Device); + rect_i.right--; } - CFX_Matrix ctm = GetCTM(); - FX_FLOAT fScaleX = FXSYS_fabs(ctm.a); - FX_FLOAT fScaleY = FXSYS_fabs(ctm.d); - FX_RECT rect = bbox.GetOutterRect(); - CFX_DIBitmap bitmap, Backdrop; - if (!CreateCompatibleBitmap(&bitmap, FXSYS_round(rect.Width() * fScaleX), FXSYS_round(rect.Height() * fScaleY))) { - return FALSE; - } - if (bitmap.HasAlpha()) { - bitmap.Clear(0); - Backdrop.Copy(&bitmap); + } + if (rect_i.Height() >= height + 1) { + if (rect_f.top - (FX_FLOAT)(rect_i.top) > + (FX_FLOAT)(rect_i.bottom) - rect_f.bottom) { + rect_i.top++; } else { - if (!m_pDeviceDriver->GetDIBits(&bitmap, rect.left, rect.top, NULL)) { - return FALSE; - } - Backdrop.Copy(&bitmap); - } - CFX_FxgeDevice bitmap_device; - bitmap_device.Attach(&bitmap, 0, FALSE, &Backdrop, TRUE); - CFX_AffineMatrix matrix; - if (pObject2Device) { - matrix = *pObject2Device; + rect_i.bottom--; } - matrix.TranslateI(-rect.left, -rect.top); - matrix.Concat(fScaleX, 0, 0, fScaleY, 0, 0); - if (!bitmap_device.GetDeviceDriver()->DrawPath(pPathData, &matrix, pGraphState, fill_color, stroke_color, fill_mode, alpha_flag, pIccTransform, blend_type)) { - return FALSE; - } - FX_RECT src_rect(0, 0, FXSYS_round(rect.Width() * fScaleX), FXSYS_round(rect.Height() * fScaleY)); - return m_pDeviceDriver->SetDIBits(&bitmap, 0, &src_rect, rect.left, rect.top, FXDIB_BLEND_NORMAL); - } - return m_pDeviceDriver->DrawPath(pPathData, pObject2Device, pGraphState, fill_color, stroke_color, fill_mode, alpha_flag, pIccTransform, blend_type); -} -FX_BOOL CFX_RenderDevice::SetPixel(int x, int y, FX_DWORD color, int alpha_flag, void* pIccTransform) -{ - if (m_pDeviceDriver->SetPixel(x, y, color, alpha_flag, pIccTransform)) { + } + if (FillRect(&rect_i, fill_color, alpha_flag, pIccTransform, + blend_type)) { return TRUE; + } } - FX_RECT rect(x, y, x + 1, y + 1); - return FillRect(&rect, color, alpha_flag, pIccTransform); -} -FX_BOOL CFX_RenderDevice::FillRect(const FX_RECT* pRect, FX_DWORD fill_color, int alpha_flag, void* pIccTransform, int blend_type) -{ - if (m_pDeviceDriver->FillRect(pRect, fill_color, alpha_flag, pIccTransform, blend_type)) { - return TRUE; + } + if ((fill_mode & 3) && stroke_alpha == 0 && !(fill_mode & FX_FILL_STROKE) && + !(fill_mode & FX_FILL_TEXT_MODE)) { + CFX_PathData newPath; + FX_BOOL bThin = FALSE; + if (pPathData->GetZeroAreaPath(newPath, (CFX_Matrix*)pObject2Device, bThin, + m_pDeviceDriver->GetDriverType())) { + CFX_GraphStateData graphState; + graphState.m_LineWidth = 0.0f; + FX_DWORD strokecolor = fill_color; + if (bThin) { + if (FXGETFLAG_COLORTYPE(alpha_flag)) { + FXSETFLAG_ALPHA_STROKE(alpha_flag, fill_alpha >> 2); + } else { + strokecolor = + (((fill_alpha >> 2) << 24) | (strokecolor & 0x00ffffff)); + } + } + CFX_AffineMatrix* pMatrix = NULL; + if (pObject2Device && !pObject2Device->IsIdentity()) { + pMatrix = (CFX_AffineMatrix*)pObject2Device; + } + int smooth_path = FX_ZEROAREA_FILL; + if (fill_mode & FXFILL_NOPATHSMOOTH) { + smooth_path |= FXFILL_NOPATHSMOOTH; + } + m_pDeviceDriver->DrawPath(&newPath, pMatrix, &graphState, 0, strokecolor, + smooth_path, alpha_flag, pIccTransform, + blend_type); } + } + if ((fill_mode & 3) && fill_alpha && stroke_alpha < 0xff && + (fill_mode & FX_FILL_STROKE)) { if (!(m_RenderCaps & FXRC_GET_BITS)) { - return FALSE; + return FALSE; } - CFX_DIBitmap bitmap; - if (!CreateCompatibleBitmap(&bitmap, pRect->Width(), pRect->Height())) { - return FALSE; + CFX_FloatRect bbox; + if (pGraphState) { + bbox = pPathData->GetBoundingBox(pGraphState->m_LineWidth, + pGraphState->m_MiterLimit); + } else { + bbox = pPathData->GetBoundingBox(); } - if (!m_pDeviceDriver->GetDIBits(&bitmap, pRect->left, pRect->top)) { - return FALSE; + if (pObject2Device) { + bbox.Transform(pObject2Device); } - if (!bitmap.CompositeRect(0, 0, pRect->Width(), pRect->Height(), fill_color, alpha_flag, pIccTransform)) { + CFX_Matrix ctm = GetCTM(); + FX_FLOAT fScaleX = FXSYS_fabs(ctm.a); + FX_FLOAT fScaleY = FXSYS_fabs(ctm.d); + FX_RECT rect = bbox.GetOutterRect(); + CFX_DIBitmap bitmap, Backdrop; + if (!CreateCompatibleBitmap(&bitmap, FXSYS_round(rect.Width() * fScaleX), + FXSYS_round(rect.Height() * fScaleY))) { + return FALSE; + } + if (bitmap.HasAlpha()) { + bitmap.Clear(0); + Backdrop.Copy(&bitmap); + } else { + if (!m_pDeviceDriver->GetDIBits(&bitmap, rect.left, rect.top, NULL)) { return FALSE; + } + Backdrop.Copy(&bitmap); + } + CFX_FxgeDevice bitmap_device; + bitmap_device.Attach(&bitmap, 0, FALSE, &Backdrop, TRUE); + CFX_AffineMatrix matrix; + if (pObject2Device) { + matrix = *pObject2Device; } - FX_RECT src_rect(0, 0, pRect->Width(), pRect->Height()); - m_pDeviceDriver->SetDIBits(&bitmap, 0, &src_rect, pRect->left, pRect->top, FXDIB_BLEND_NORMAL); + matrix.TranslateI(-rect.left, -rect.top); + matrix.Concat(fScaleX, 0, 0, fScaleY, 0, 0); + if (!bitmap_device.GetDeviceDriver()->DrawPath( + pPathData, &matrix, pGraphState, fill_color, stroke_color, + fill_mode, alpha_flag, pIccTransform, blend_type)) { + return FALSE; + } + FX_RECT src_rect(0, 0, FXSYS_round(rect.Width() * fScaleX), + FXSYS_round(rect.Height() * fScaleY)); + return m_pDeviceDriver->SetDIBits(&bitmap, 0, &src_rect, rect.left, + rect.top, FXDIB_BLEND_NORMAL); + } + return m_pDeviceDriver->DrawPath(pPathData, pObject2Device, pGraphState, + fill_color, stroke_color, fill_mode, + alpha_flag, pIccTransform, blend_type); +} +FX_BOOL CFX_RenderDevice::SetPixel(int x, + int y, + FX_DWORD color, + int alpha_flag, + void* pIccTransform) { + if (m_pDeviceDriver->SetPixel(x, y, color, alpha_flag, pIccTransform)) { return TRUE; + } + FX_RECT rect(x, y, x + 1, y + 1); + return FillRect(&rect, color, alpha_flag, pIccTransform); } -FX_BOOL CFX_RenderDevice::DrawCosmeticLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2, FX_DWORD color, - int fill_mode, int alpha_flag, void* pIccTransform, int blend_type) -{ - if (((m_RenderCaps & FXRC_ALPHA_PATH) && - (FXGETFLAG_COLORTYPE(alpha_flag) && FXGETFLAG_ALPHA_FILL(alpha_flag) == 0xff)) || - color >= 0xff000000) - if (m_pDeviceDriver->DrawCosmeticLine(x1, y1, x2, y2, color, alpha_flag, pIccTransform, blend_type)) { - return TRUE; - } - CFX_GraphStateData graph_state; - CFX_PathData path; - path.SetPointCount(2); - path.SetPoint(0, x1, y1, FXPT_MOVETO); - path.SetPoint(1, x2, y2, FXPT_LINETO); - return m_pDeviceDriver->DrawPath(&path, NULL, &graph_state, 0, color, fill_mode, alpha_flag, pIccTransform, blend_type); +FX_BOOL CFX_RenderDevice::FillRect(const FX_RECT* pRect, + FX_DWORD fill_color, + int alpha_flag, + void* pIccTransform, + int blend_type) { + if (m_pDeviceDriver->FillRect(pRect, fill_color, alpha_flag, pIccTransform, + blend_type)) { + return TRUE; + } + if (!(m_RenderCaps & FXRC_GET_BITS)) { + return FALSE; + } + CFX_DIBitmap bitmap; + if (!CreateCompatibleBitmap(&bitmap, pRect->Width(), pRect->Height())) { + return FALSE; + } + if (!m_pDeviceDriver->GetDIBits(&bitmap, pRect->left, pRect->top)) { + return FALSE; + } + if (!bitmap.CompositeRect(0, 0, pRect->Width(), pRect->Height(), fill_color, + alpha_flag, pIccTransform)) { + return FALSE; + } + FX_RECT src_rect(0, 0, pRect->Width(), pRect->Height()); + m_pDeviceDriver->SetDIBits(&bitmap, 0, &src_rect, pRect->left, pRect->top, + FXDIB_BLEND_NORMAL); + return TRUE; } -FX_BOOL CFX_RenderDevice::GetDIBits(CFX_DIBitmap* pBitmap, int left, int top, void* pIccTransform) -{ - if (!(m_RenderCaps & FXRC_GET_BITS)) { - return FALSE; +FX_BOOL CFX_RenderDevice::DrawCosmeticLine(FX_FLOAT x1, + FX_FLOAT y1, + FX_FLOAT x2, + FX_FLOAT y2, + FX_DWORD color, + int fill_mode, + int alpha_flag, + void* pIccTransform, + int blend_type) { + if (((m_RenderCaps & FXRC_ALPHA_PATH) && + (FXGETFLAG_COLORTYPE(alpha_flag) && + FXGETFLAG_ALPHA_FILL(alpha_flag) == 0xff)) || + color >= 0xff000000) + if (m_pDeviceDriver->DrawCosmeticLine(x1, y1, x2, y2, color, alpha_flag, + pIccTransform, blend_type)) { + return TRUE; } - return m_pDeviceDriver->GetDIBits(pBitmap, left, top, pIccTransform); + CFX_GraphStateData graph_state; + CFX_PathData path; + path.SetPointCount(2); + path.SetPoint(0, x1, y1, FXPT_MOVETO); + path.SetPoint(1, x2, y2, FXPT_LINETO); + return m_pDeviceDriver->DrawPath(&path, NULL, &graph_state, 0, color, + fill_mode, alpha_flag, pIccTransform, + blend_type); } -CFX_DIBitmap* CFX_RenderDevice::GetBackDrop() -{ - return m_pDeviceDriver->GetBackDrop(); +FX_BOOL CFX_RenderDevice::GetDIBits(CFX_DIBitmap* pBitmap, + int left, + int top, + void* pIccTransform) { + if (!(m_RenderCaps & FXRC_GET_BITS)) { + return FALSE; + } + return m_pDeviceDriver->GetDIBits(pBitmap, left, top, pIccTransform); } -FX_BOOL CFX_RenderDevice::SetDIBits(const CFX_DIBSource* pBitmap, int left, int top, int blend_mode, - void* pIccTransform) -{ - ASSERT(!pBitmap->IsAlphaMask()); - CFX_AffineMatrix ctm = GetCTM(); - FX_FLOAT fScaleX = FXSYS_fabs(ctm.a); - FX_FLOAT fScaleY = FXSYS_fabs(ctm.d); - FX_RECT dest_rect(left, top, FXSYS_round(left + pBitmap->GetWidth() / fScaleX), FXSYS_round(top + pBitmap->GetHeight() / fScaleY)); - dest_rect.Intersect(m_ClipBox); - if (dest_rect.IsEmpty()) { - return TRUE; +CFX_DIBitmap* CFX_RenderDevice::GetBackDrop() { + return m_pDeviceDriver->GetBackDrop(); +} +FX_BOOL CFX_RenderDevice::SetDIBits(const CFX_DIBSource* pBitmap, + int left, + int top, + int blend_mode, + void* pIccTransform) { + ASSERT(!pBitmap->IsAlphaMask()); + CFX_AffineMatrix ctm = GetCTM(); + FX_FLOAT fScaleX = FXSYS_fabs(ctm.a); + FX_FLOAT fScaleY = FXSYS_fabs(ctm.d); + FX_RECT dest_rect(left, top, + FXSYS_round(left + pBitmap->GetWidth() / fScaleX), + FXSYS_round(top + pBitmap->GetHeight() / fScaleY)); + dest_rect.Intersect(m_ClipBox); + if (dest_rect.IsEmpty()) { + return TRUE; + } + FX_RECT src_rect(dest_rect.left - left, dest_rect.top - top, + dest_rect.left - left + dest_rect.Width(), + dest_rect.top - top + dest_rect.Height()); + src_rect.left = FXSYS_round(src_rect.left * fScaleX); + src_rect.top = FXSYS_round(src_rect.top * fScaleY); + src_rect.right = FXSYS_round(src_rect.right * fScaleX); + src_rect.bottom = FXSYS_round(src_rect.bottom * fScaleY); + if ((blend_mode != FXDIB_BLEND_NORMAL && !(m_RenderCaps & FXRC_BLEND_MODE)) || + (pBitmap->HasAlpha() && !(m_RenderCaps & FXRC_ALPHA_IMAGE))) { + if (!(m_RenderCaps & FXRC_GET_BITS)) { + return FALSE; } - FX_RECT src_rect(dest_rect.left - left, dest_rect.top - top, - dest_rect.left - left + dest_rect.Width(), dest_rect.top - top + dest_rect.Height()); - src_rect.left = FXSYS_round(src_rect.left * fScaleX); - src_rect.top = FXSYS_round(src_rect.top * fScaleY); - src_rect.right = FXSYS_round(src_rect.right * fScaleX); - src_rect.bottom = FXSYS_round(src_rect.bottom * fScaleY); - if ((blend_mode != FXDIB_BLEND_NORMAL && !(m_RenderCaps & FXRC_BLEND_MODE)) || - (pBitmap->HasAlpha() && !(m_RenderCaps & FXRC_ALPHA_IMAGE))) { - if (!(m_RenderCaps & FXRC_GET_BITS)) { - return FALSE; - } - int bg_pixel_width = FXSYS_round(dest_rect.Width() * fScaleX); - int bg_pixel_height = FXSYS_round(dest_rect.Height() * fScaleY); - CFX_DIBitmap background; - if (!background.Create(bg_pixel_width, bg_pixel_height, - (m_RenderCaps & FXRC_CMYK_OUTPUT) ? FXDIB_Cmyk : FXDIB_Rgb32)) { - return FALSE; - } - if (!m_pDeviceDriver->GetDIBits(&background, dest_rect.left, dest_rect.top)) { - return FALSE; - } - if (!background.CompositeBitmap(0, 0, bg_pixel_width, bg_pixel_height, - pBitmap, src_rect.left, src_rect.top, - blend_mode, NULL, FALSE, pIccTransform)) { - return FALSE; - } - FX_RECT src_rect(0, 0, bg_pixel_width, bg_pixel_height); - return m_pDeviceDriver->SetDIBits(&background, 0, &src_rect, dest_rect.left, dest_rect.top, FXDIB_BLEND_NORMAL); + int bg_pixel_width = FXSYS_round(dest_rect.Width() * fScaleX); + int bg_pixel_height = FXSYS_round(dest_rect.Height() * fScaleY); + CFX_DIBitmap background; + if (!background.Create( + bg_pixel_width, bg_pixel_height, + (m_RenderCaps & FXRC_CMYK_OUTPUT) ? FXDIB_Cmyk : FXDIB_Rgb32)) { + return FALSE; } - return m_pDeviceDriver->SetDIBits(pBitmap, 0, &src_rect, dest_rect.left, dest_rect.top, blend_mode, 0, pIccTransform); -} -FX_BOOL CFX_RenderDevice::StretchDIBits(const CFX_DIBSource* pBitmap, int left, int top, - int dest_width, int dest_height, FX_DWORD flags, - void* pIccTransform, int blend_mode) -{ - FX_RECT dest_rect(left, top, left + dest_width, top + dest_height); - FX_RECT clip_box = m_ClipBox; - clip_box.Intersect(dest_rect); - if (clip_box.IsEmpty()) { - return TRUE; + if (!m_pDeviceDriver->GetDIBits(&background, dest_rect.left, + dest_rect.top)) { + return FALSE; + } + if (!background.CompositeBitmap(0, 0, bg_pixel_width, bg_pixel_height, + pBitmap, src_rect.left, src_rect.top, + blend_mode, NULL, FALSE, pIccTransform)) { + return FALSE; } - return m_pDeviceDriver->StretchDIBits(pBitmap, 0, left, top, dest_width, dest_height, &clip_box, flags, 0, pIccTransform, blend_mode); + FX_RECT src_rect(0, 0, bg_pixel_width, bg_pixel_height); + return m_pDeviceDriver->SetDIBits(&background, 0, &src_rect, dest_rect.left, + dest_rect.top, FXDIB_BLEND_NORMAL); + } + return m_pDeviceDriver->SetDIBits(pBitmap, 0, &src_rect, dest_rect.left, + dest_rect.top, blend_mode, 0, + pIccTransform); +} +FX_BOOL CFX_RenderDevice::StretchDIBits(const CFX_DIBSource* pBitmap, + int left, + int top, + int dest_width, + int dest_height, + FX_DWORD flags, + void* pIccTransform, + int blend_mode) { + FX_RECT dest_rect(left, top, left + dest_width, top + dest_height); + FX_RECT clip_box = m_ClipBox; + clip_box.Intersect(dest_rect); + if (clip_box.IsEmpty()) { + return TRUE; + } + return m_pDeviceDriver->StretchDIBits(pBitmap, 0, left, top, dest_width, + dest_height, &clip_box, flags, 0, + pIccTransform, blend_mode); } -FX_BOOL CFX_RenderDevice::SetBitMask(const CFX_DIBSource* pBitmap, int left, int top, FX_DWORD argb, - int alpha_flag, void* pIccTransform) -{ - FX_RECT src_rect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight()); - return m_pDeviceDriver->SetDIBits(pBitmap, argb, &src_rect, left, top, FXDIB_BLEND_NORMAL, alpha_flag, pIccTransform); +FX_BOOL CFX_RenderDevice::SetBitMask(const CFX_DIBSource* pBitmap, + int left, + int top, + FX_DWORD argb, + int alpha_flag, + void* pIccTransform) { + FX_RECT src_rect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight()); + return m_pDeviceDriver->SetDIBits(pBitmap, argb, &src_rect, left, top, + FXDIB_BLEND_NORMAL, alpha_flag, + pIccTransform); } -FX_BOOL CFX_RenderDevice::StretchBitMask(const CFX_DIBSource* pBitmap, int left, int top, - int dest_width, int dest_height, FX_DWORD argb, FX_DWORD flags, - int alpha_flag, void* pIccTransform) -{ - FX_RECT dest_rect(left, top, left + dest_width, top + dest_height); - FX_RECT clip_box = m_ClipBox; - clip_box.Intersect(dest_rect); - return m_pDeviceDriver->StretchDIBits(pBitmap, argb, left, top, dest_width, dest_height, &clip_box, flags, alpha_flag, pIccTransform); +FX_BOOL CFX_RenderDevice::StretchBitMask(const CFX_DIBSource* pBitmap, + int left, + int top, + int dest_width, + int dest_height, + FX_DWORD argb, + FX_DWORD flags, + int alpha_flag, + void* pIccTransform) { + FX_RECT dest_rect(left, top, left + dest_width, top + dest_height); + FX_RECT clip_box = m_ClipBox; + clip_box.Intersect(dest_rect); + return m_pDeviceDriver->StretchDIBits(pBitmap, argb, left, top, dest_width, + dest_height, &clip_box, flags, + alpha_flag, pIccTransform); } -FX_BOOL CFX_RenderDevice::StartDIBits(const CFX_DIBSource* pBitmap, int bitmap_alpha, FX_DWORD argb, - const CFX_AffineMatrix* pMatrix, FX_DWORD flags, void*& handle, - int alpha_flag, void* pIccTransform, int blend_mode) -{ - return m_pDeviceDriver->StartDIBits(pBitmap, bitmap_alpha, argb, pMatrix, flags, handle, alpha_flag, pIccTransform, blend_mode); +FX_BOOL CFX_RenderDevice::StartDIBits(const CFX_DIBSource* pBitmap, + int bitmap_alpha, + FX_DWORD argb, + const CFX_AffineMatrix* pMatrix, + FX_DWORD flags, + void*& handle, + int alpha_flag, + void* pIccTransform, + int blend_mode) { + return m_pDeviceDriver->StartDIBits(pBitmap, bitmap_alpha, argb, pMatrix, + flags, handle, alpha_flag, pIccTransform, + blend_mode); } -FX_BOOL CFX_RenderDevice::ContinueDIBits(void* handle, IFX_Pause* pPause) -{ - return m_pDeviceDriver->ContinueDIBits(handle, pPause); +FX_BOOL CFX_RenderDevice::ContinueDIBits(void* handle, IFX_Pause* pPause) { + return m_pDeviceDriver->ContinueDIBits(handle, pPause); } -void CFX_RenderDevice::CancelDIBits(void* handle) -{ - m_pDeviceDriver->CancelDIBits(handle); +void CFX_RenderDevice::CancelDIBits(void* handle) { + m_pDeviceDriver->CancelDIBits(handle); } diff --git a/core/src/fxge/ge/fx_ge_font.cpp b/core/src/fxge/ge/fx_ge_font.cpp index 6a950bf20b..e701ee9492 100644 --- a/core/src/fxge/ge/fx_ge_font.cpp +++ b/core/src/fxge/ge/fx_ge_font.cpp @@ -7,426 +7,426 @@ #include "../../../include/fxge/fx_ge.h" #include "../../../include/fxge/fx_freetype.h" #include "text_int.h" -#define EM_ADJUST(em, a) (em == 0?(a): (a)*1000/em) -extern void _FPDFAPI_GetInternalFontData(int id1, const uint8_t*& data, FX_DWORD& size); -CFX_Font::CFX_Font() -{ - m_pSubstFont = NULL; - m_Face = NULL; - m_bEmbedded = FALSE; - m_bVertical = FALSE; - m_pFontData = NULL; - m_pFontDataAllocation = NULL; - m_dwSize = 0; - m_pOwnedStream = NULL; - m_pGsubData = NULL; - m_pPlatformFont = NULL; - m_pPlatformFontCollection = NULL; - m_pDwFont = NULL; - m_hHandle = NULL; - m_bDwLoaded = FALSE; +#define EM_ADJUST(em, a) (em == 0 ? (a) : (a)*1000 / em) +extern void _FPDFAPI_GetInternalFontData(int id1, + const uint8_t*& data, + FX_DWORD& size); +CFX_Font::CFX_Font() { + m_pSubstFont = NULL; + m_Face = NULL; + m_bEmbedded = FALSE; + m_bVertical = FALSE; + m_pFontData = NULL; + m_pFontDataAllocation = NULL; + m_dwSize = 0; + m_pOwnedStream = NULL; + m_pGsubData = NULL; + m_pPlatformFont = NULL; + m_pPlatformFontCollection = NULL; + m_pDwFont = NULL; + m_hHandle = NULL; + m_bDwLoaded = FALSE; } -CFX_Font::~CFX_Font() -{ - delete m_pSubstFont; - m_pSubstFont = NULL; - if (m_pFontDataAllocation) { - FX_Free(m_pFontDataAllocation); - m_pFontDataAllocation = NULL; - } - if (m_Face) { - if (FXFT_Get_Face_External_Stream(m_Face)) { - FXFT_Clear_Face_External_Stream(m_Face); - } - if(m_bEmbedded) { - DeleteFace(); - } else { - CFX_GEModule::Get()->GetFontMgr()->ReleaseFace(m_Face); - } - } - if (m_pOwnedStream) { - FX_Free(m_pOwnedStream); - m_pOwnedStream = NULL; +CFX_Font::~CFX_Font() { + delete m_pSubstFont; + m_pSubstFont = NULL; + if (m_pFontDataAllocation) { + FX_Free(m_pFontDataAllocation); + m_pFontDataAllocation = NULL; + } + if (m_Face) { + if (FXFT_Get_Face_External_Stream(m_Face)) { + FXFT_Clear_Face_External_Stream(m_Face); } - if (m_pGsubData) { - FX_Free(m_pGsubData); - m_pGsubData = NULL; + if (m_bEmbedded) { + DeleteFace(); + } else { + CFX_GEModule::Get()->GetFontMgr()->ReleaseFace(m_Face); } -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - ReleasePlatformResource(); + } + if (m_pOwnedStream) { + FX_Free(m_pOwnedStream); + m_pOwnedStream = NULL; + } + if (m_pGsubData) { + FX_Free(m_pGsubData); + m_pGsubData = NULL; + } +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + ReleasePlatformResource(); #endif } -void CFX_Font::DeleteFace() -{ - FXFT_Done_Face(m_Face); - m_Face = NULL; +void CFX_Font::DeleteFace() { + FXFT_Done_Face(m_Face); + m_Face = NULL; } -FX_BOOL CFX_Font::LoadSubst(const CFX_ByteString& face_name, FX_BOOL bTrueType, FX_DWORD flags, - int weight, int italic_angle, int CharsetCP, FX_BOOL bVertical) -{ - m_bEmbedded = FALSE; - m_bVertical = bVertical; - m_pSubstFont = new CFX_SubstFont; - m_Face = CFX_GEModule::Get()->GetFontMgr()->FindSubstFont(face_name, bTrueType, flags, weight, italic_angle, - CharsetCP, m_pSubstFont); -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - if(m_pSubstFont->m_ExtHandle) { - m_pPlatformFont = m_pSubstFont->m_ExtHandle; - m_pSubstFont->m_ExtHandle = NULL; - } +FX_BOOL CFX_Font::LoadSubst(const CFX_ByteString& face_name, + FX_BOOL bTrueType, + FX_DWORD flags, + int weight, + int italic_angle, + int CharsetCP, + FX_BOOL bVertical) { + m_bEmbedded = FALSE; + m_bVertical = bVertical; + m_pSubstFont = new CFX_SubstFont; + m_Face = CFX_GEModule::Get()->GetFontMgr()->FindSubstFont( + face_name, bTrueType, flags, weight, italic_angle, CharsetCP, + m_pSubstFont); +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + if (m_pSubstFont->m_ExtHandle) { + m_pPlatformFont = m_pSubstFont->m_ExtHandle; + m_pSubstFont->m_ExtHandle = NULL; + } #endif - if (m_Face) { - m_pFontData = FXFT_Get_Face_Stream_Base(m_Face); - m_dwSize = FXFT_Get_Face_Stream_Size(m_Face); - } - return TRUE; + if (m_Face) { + m_pFontData = FXFT_Get_Face_Stream_Base(m_Face); + m_dwSize = FXFT_Get_Face_Stream_Size(m_Face); + } + return TRUE; } extern "C" { - unsigned long _FTStreamRead(FXFT_Stream stream, unsigned long offset, - unsigned char* buffer, unsigned long count) - { - if (count == 0) { - return 0; - } - IFX_FileRead* pFile = (IFX_FileRead*)stream->descriptor.pointer; - int res = pFile->ReadBlock(buffer, offset, count); - if (res) { - return count; - } - return 0; - } - void _FTStreamClose(FXFT_Stream stream) - { - } +unsigned long _FTStreamRead(FXFT_Stream stream, + unsigned long offset, + unsigned char* buffer, + unsigned long count) { + if (count == 0) { + return 0; + } + IFX_FileRead* pFile = (IFX_FileRead*)stream->descriptor.pointer; + int res = pFile->ReadBlock(buffer, offset, count); + if (res) { + return count; + } + return 0; +} +void _FTStreamClose(FXFT_Stream stream) {} }; -FX_BOOL _LoadFile(FXFT_Library library, FXFT_Face* Face, IFX_FileRead* pFile, FXFT_Stream* stream) -{ - FXFT_Stream stream1 = (FXFT_Stream)FX_Alloc(uint8_t, sizeof (FXFT_StreamRec)); - stream1->base = NULL; - stream1->size = (unsigned long)pFile->GetSize(); - stream1->pos = 0; - stream1->descriptor.pointer = pFile; - stream1->close = _FTStreamClose; - stream1->read = _FTStreamRead; - FXFT_Open_Args args; - args.flags = FT_OPEN_STREAM; - args.stream = stream1; - if (FXFT_Open_Face(library, &args, 0, Face)) { - FX_Free(stream1); - return FALSE; - } - if (stream) { - *stream = stream1; - } - return TRUE; +FX_BOOL _LoadFile(FXFT_Library library, + FXFT_Face* Face, + IFX_FileRead* pFile, + FXFT_Stream* stream) { + FXFT_Stream stream1 = (FXFT_Stream)FX_Alloc(uint8_t, sizeof(FXFT_StreamRec)); + stream1->base = NULL; + stream1->size = (unsigned long)pFile->GetSize(); + stream1->pos = 0; + stream1->descriptor.pointer = pFile; + stream1->close = _FTStreamClose; + stream1->read = _FTStreamRead; + FXFT_Open_Args args; + args.flags = FT_OPEN_STREAM; + args.stream = stream1; + if (FXFT_Open_Face(library, &args, 0, Face)) { + FX_Free(stream1); + return FALSE; + } + if (stream) { + *stream = stream1; + } + return TRUE; } -FX_BOOL CFX_Font::LoadFile(IFX_FileRead* pFile) -{ - m_bEmbedded = FALSE; - FXFT_Library library; - if (CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary == NULL) { - FXFT_Init_FreeType(&CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary); - } - library = CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary; - FXFT_Stream stream = NULL; - if (!_LoadFile(library, &m_Face, pFile, &stream)) { - return FALSE; - } - m_pOwnedStream = stream; - FXFT_Set_Pixel_Sizes(m_Face, 0, 64); - return TRUE; +FX_BOOL CFX_Font::LoadFile(IFX_FileRead* pFile) { + m_bEmbedded = FALSE; + FXFT_Library library; + if (CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary == NULL) { + FXFT_Init_FreeType(&CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary); + } + library = CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary; + FXFT_Stream stream = NULL; + if (!_LoadFile(library, &m_Face, pFile, &stream)) { + return FALSE; + } + m_pOwnedStream = stream; + FXFT_Set_Pixel_Sizes(m_Face, 0, 64); + return TRUE; } -int CFX_Font::GetGlyphWidth(FX_DWORD glyph_index) -{ - if (!m_Face) { - return 0; - } - if (m_pSubstFont && (m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM)) { - AdjustMMParams(glyph_index, 0, 0); - } - int err = FXFT_Load_Glyph(m_Face, glyph_index, FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); - if (err) { - return 0; - } - int width = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Glyph_HoriAdvance(m_Face)); - return width; +int CFX_Font::GetGlyphWidth(FX_DWORD glyph_index) { + if (!m_Face) { + return 0; + } + if (m_pSubstFont && (m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM)) { + AdjustMMParams(glyph_index, 0, 0); + } + int err = FXFT_Load_Glyph( + m_Face, glyph_index, + FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); + if (err) { + return 0; + } + int width = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), + FXFT_Get_Glyph_HoriAdvance(m_Face)); + return width; } -static FXFT_Face FT_LoadFont(uint8_t* pData, int size) -{ - FXFT_Library library; - if (CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary == NULL) { - FXFT_Init_FreeType(&CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary); - } - library = CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary; - FXFT_Face face = NULL; - int error = FXFT_New_Memory_Face(library, pData, size, 0, &face); - if (error) { - return NULL; - } - error = FXFT_Set_Pixel_Sizes(face, 64, 64); - if (error) { - return NULL; - } - return face; +static FXFT_Face FT_LoadFont(uint8_t* pData, int size) { + FXFT_Library library; + if (CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary == NULL) { + FXFT_Init_FreeType(&CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary); + } + library = CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary; + FXFT_Face face = NULL; + int error = FXFT_New_Memory_Face(library, pData, size, 0, &face); + if (error) { + return NULL; + } + error = FXFT_Set_Pixel_Sizes(face, 64, 64); + if (error) { + return NULL; + } + return face; } -FX_BOOL CFX_Font::LoadEmbedded(const uint8_t* data, FX_DWORD size) -{ - m_pFontDataAllocation = FX_Alloc(uint8_t, size); - FXSYS_memcpy(m_pFontDataAllocation, data, size); - m_Face = FT_LoadFont((uint8_t*)m_pFontDataAllocation, size); - m_pFontData = (uint8_t*)m_pFontDataAllocation; - m_bEmbedded = TRUE; - m_dwSize = size; - return m_Face != NULL; +FX_BOOL CFX_Font::LoadEmbedded(const uint8_t* data, FX_DWORD size) { + m_pFontDataAllocation = FX_Alloc(uint8_t, size); + FXSYS_memcpy(m_pFontDataAllocation, data, size); + m_Face = FT_LoadFont((uint8_t*)m_pFontDataAllocation, size); + m_pFontData = (uint8_t*)m_pFontDataAllocation; + m_bEmbedded = TRUE; + m_dwSize = size; + return m_Face != NULL; } -FX_BOOL CFX_Font::IsTTFont() -{ - if (m_Face == NULL) { - return FALSE; - } - return FXFT_Is_Face_TT_OT(m_Face) == FXFT_FACE_FLAG_SFNT; +FX_BOOL CFX_Font::IsTTFont() { + if (m_Face == NULL) { + return FALSE; + } + return FXFT_Is_Face_TT_OT(m_Face) == FXFT_FACE_FLAG_SFNT; } -int CFX_Font::GetAscent() const -{ - if (m_Face == NULL) { - return 0; - } - int ascent = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_Ascender(m_Face)); - return ascent; +int CFX_Font::GetAscent() const { + if (m_Face == NULL) { + return 0; + } + int ascent = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), + FXFT_Get_Face_Ascender(m_Face)); + return ascent; } -int CFX_Font::GetDescent() const -{ - if (m_Face == NULL) { - return 0; - } - int descent = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_Descender(m_Face)); - return descent; +int CFX_Font::GetDescent() const { + if (m_Face == NULL) { + return 0; + } + int descent = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), + FXFT_Get_Face_Descender(m_Face)); + return descent; } -FX_BOOL CFX_Font::GetGlyphBBox(FX_DWORD glyph_index, FX_RECT &bbox) -{ - if (m_Face == NULL) { - return FALSE; - } - if (FXFT_Is_Face_Tricky(m_Face)) { - int error = FXFT_Set_Char_Size(m_Face, 0, 1000 * 64, 72, 72); - if (error) { - return FALSE; - } - error = FXFT_Load_Glyph(m_Face, glyph_index, FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); - if (error) { - return FALSE; - } - FXFT_BBox cbox; - FT_Glyph glyph; - error = FXFT_Get_Glyph(((FXFT_Face)m_Face)->glyph, &glyph); - if (error) { - return FALSE; - } - FXFT_Glyph_Get_CBox(glyph, FXFT_GLYPH_BBOX_PIXELS, &cbox); - int pixel_size_x = ((FXFT_Face)m_Face)->size->metrics.x_ppem, - pixel_size_y = ((FXFT_Face)m_Face)->size->metrics.y_ppem; - if (pixel_size_x == 0 || pixel_size_y == 0) { - bbox.left = cbox.xMin; - bbox.right = cbox.xMax; - bbox.top = cbox.yMax; - bbox.bottom = cbox.yMin; - } else { - bbox.left = cbox.xMin * 1000 / pixel_size_x; - bbox.right = cbox.xMax * 1000 / pixel_size_x; - bbox.top = cbox.yMax * 1000 / pixel_size_y; - bbox.bottom = cbox.yMin * 1000 / pixel_size_y; - } - if (bbox.top > FXFT_Get_Face_Ascender(m_Face)) { - bbox.top = FXFT_Get_Face_Ascender(m_Face); - } - if (bbox.bottom < FXFT_Get_Face_Descender(m_Face)) { - bbox.bottom = FXFT_Get_Face_Descender(m_Face); - } - FT_Done_Glyph(glyph); - return FXFT_Set_Pixel_Sizes(m_Face, 0, 64) == 0; +FX_BOOL CFX_Font::GetGlyphBBox(FX_DWORD glyph_index, FX_RECT& bbox) { + if (m_Face == NULL) { + return FALSE; + } + if (FXFT_Is_Face_Tricky(m_Face)) { + int error = FXFT_Set_Char_Size(m_Face, 0, 1000 * 64, 72, 72); + if (error) { + return FALSE; } - if (FXFT_Load_Glyph(m_Face, glyph_index, FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) { - return FALSE; + error = FXFT_Load_Glyph(m_Face, glyph_index, + FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); + if (error) { + return FALSE; } - int em = FXFT_Get_Face_UnitsPerEM(m_Face); - if (em == 0) { - bbox.left = FXFT_Get_Glyph_HoriBearingX(m_Face); - bbox.bottom = FXFT_Get_Glyph_HoriBearingY(m_Face); - bbox.top = bbox.bottom - FXFT_Get_Glyph_Height(m_Face); - bbox.right = bbox.left + FXFT_Get_Glyph_Width(m_Face); + FXFT_BBox cbox; + FT_Glyph glyph; + error = FXFT_Get_Glyph(((FXFT_Face)m_Face)->glyph, &glyph); + if (error) { + return FALSE; + } + FXFT_Glyph_Get_CBox(glyph, FXFT_GLYPH_BBOX_PIXELS, &cbox); + int pixel_size_x = ((FXFT_Face)m_Face)->size->metrics.x_ppem, + pixel_size_y = ((FXFT_Face)m_Face)->size->metrics.y_ppem; + if (pixel_size_x == 0 || pixel_size_y == 0) { + bbox.left = cbox.xMin; + bbox.right = cbox.xMax; + bbox.top = cbox.yMax; + bbox.bottom = cbox.yMin; } else { - bbox.left = FXFT_Get_Glyph_HoriBearingX(m_Face) * 1000 / em; - bbox.top = (FXFT_Get_Glyph_HoriBearingY(m_Face) - FXFT_Get_Glyph_Height(m_Face)) * 1000 / em; - bbox.right = (FXFT_Get_Glyph_HoriBearingX(m_Face) + FXFT_Get_Glyph_Width(m_Face)) * 1000 / em; - bbox.bottom = (FXFT_Get_Glyph_HoriBearingY(m_Face)) * 1000 / em; - } - return TRUE; + bbox.left = cbox.xMin * 1000 / pixel_size_x; + bbox.right = cbox.xMax * 1000 / pixel_size_x; + bbox.top = cbox.yMax * 1000 / pixel_size_y; + bbox.bottom = cbox.yMin * 1000 / pixel_size_y; + } + if (bbox.top > FXFT_Get_Face_Ascender(m_Face)) { + bbox.top = FXFT_Get_Face_Ascender(m_Face); + } + if (bbox.bottom < FXFT_Get_Face_Descender(m_Face)) { + bbox.bottom = FXFT_Get_Face_Descender(m_Face); + } + FT_Done_Glyph(glyph); + return FXFT_Set_Pixel_Sizes(m_Face, 0, 64) == 0; + } + if (FXFT_Load_Glyph( + m_Face, glyph_index, + FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) { + return FALSE; + } + int em = FXFT_Get_Face_UnitsPerEM(m_Face); + if (em == 0) { + bbox.left = FXFT_Get_Glyph_HoriBearingX(m_Face); + bbox.bottom = FXFT_Get_Glyph_HoriBearingY(m_Face); + bbox.top = bbox.bottom - FXFT_Get_Glyph_Height(m_Face); + bbox.right = bbox.left + FXFT_Get_Glyph_Width(m_Face); + } else { + bbox.left = FXFT_Get_Glyph_HoriBearingX(m_Face) * 1000 / em; + bbox.top = + (FXFT_Get_Glyph_HoriBearingY(m_Face) - FXFT_Get_Glyph_Height(m_Face)) * + 1000 / em; + bbox.right = + (FXFT_Get_Glyph_HoriBearingX(m_Face) + FXFT_Get_Glyph_Width(m_Face)) * + 1000 / em; + bbox.bottom = (FXFT_Get_Glyph_HoriBearingY(m_Face)) * 1000 / em; + } + return TRUE; } -FX_BOOL CFX_Font::IsItalic() -{ - if (m_Face == NULL) { - return FALSE; - } - FX_BOOL ret = FXFT_Is_Face_Italic(m_Face) == FXFT_STYLE_FLAG_ITALIC; - if (!ret) { - CFX_ByteString str(FXFT_Get_Face_Style_Name(m_Face)); - str.MakeLower(); - if (str.Find("italic") != -1) { - ret = TRUE; - } - } - return ret; +FX_BOOL CFX_Font::IsItalic() { + if (m_Face == NULL) { + return FALSE; + } + FX_BOOL ret = FXFT_Is_Face_Italic(m_Face) == FXFT_STYLE_FLAG_ITALIC; + if (!ret) { + CFX_ByteString str(FXFT_Get_Face_Style_Name(m_Face)); + str.MakeLower(); + if (str.Find("italic") != -1) { + ret = TRUE; + } + } + return ret; } -FX_BOOL CFX_Font::IsBold() -{ - if (m_Face == NULL) { - return FALSE; - } - return FXFT_Is_Face_Bold(m_Face) == FXFT_STYLE_FLAG_BOLD; +FX_BOOL CFX_Font::IsBold() { + if (m_Face == NULL) { + return FALSE; + } + return FXFT_Is_Face_Bold(m_Face) == FXFT_STYLE_FLAG_BOLD; } -FX_BOOL CFX_Font::IsFixedWidth() -{ - if (m_Face == NULL) { - return FALSE; - } - return FXFT_Is_Face_fixedwidth(m_Face); +FX_BOOL CFX_Font::IsFixedWidth() { + if (m_Face == NULL) { + return FALSE; + } + return FXFT_Is_Face_fixedwidth(m_Face); } -CFX_WideString CFX_Font::GetPsName() const -{ - if (m_Face == NULL) { - return CFX_WideString(); - } - CFX_WideString psName = CFX_WideString::FromLocal(FXFT_Get_Postscript_Name(m_Face)); - if (psName.IsEmpty()) { - psName = CFX_WideString::FromLocal("Untitled"); - } - return psName; +CFX_WideString CFX_Font::GetPsName() const { + if (m_Face == NULL) { + return CFX_WideString(); + } + CFX_WideString psName = + CFX_WideString::FromLocal(FXFT_Get_Postscript_Name(m_Face)); + if (psName.IsEmpty()) { + psName = CFX_WideString::FromLocal("Untitled"); + } + return psName; } -CFX_ByteString CFX_Font::GetFamilyName() const -{ - if (m_Face == NULL && m_pSubstFont == NULL) { - return CFX_ByteString(); - } - if (m_Face) { - return CFX_ByteString(FXFT_Get_Face_Family_Name(m_Face)); - } - return m_pSubstFont->m_Family; +CFX_ByteString CFX_Font::GetFamilyName() const { + if (m_Face == NULL && m_pSubstFont == NULL) { + return CFX_ByteString(); + } + if (m_Face) { + return CFX_ByteString(FXFT_Get_Face_Family_Name(m_Face)); + } + return m_pSubstFont->m_Family; } -CFX_ByteString CFX_Font::GetFaceName() const -{ - if (m_Face == NULL && m_pSubstFont == NULL) { - return CFX_ByteString(); - } - if (m_Face) { - CFX_ByteString facename; - CFX_ByteString style = CFX_ByteString(FXFT_Get_Face_Style_Name(m_Face)); - facename = GetFamilyName(); - if (facename.IsEmpty()) { - facename = "Untitled"; - } - if (!style.IsEmpty() && style != "Regular") { - facename += " " + style; - } - return facename; - } - return m_pSubstFont->m_Family; +CFX_ByteString CFX_Font::GetFaceName() const { + if (m_Face == NULL && m_pSubstFont == NULL) { + return CFX_ByteString(); + } + if (m_Face) { + CFX_ByteString facename; + CFX_ByteString style = CFX_ByteString(FXFT_Get_Face_Style_Name(m_Face)); + facename = GetFamilyName(); + if (facename.IsEmpty()) { + facename = "Untitled"; + } + if (!style.IsEmpty() && style != "Regular") { + facename += " " + style; + } + return facename; + } + return m_pSubstFont->m_Family; } -FX_BOOL CFX_Font::GetBBox(FX_RECT &bbox) -{ - if (m_Face == NULL) { - return FALSE; - } - int em = FXFT_Get_Face_UnitsPerEM(m_Face); - if (em == 0) { - bbox.left = FXFT_Get_Face_xMin(m_Face); - bbox.bottom = FXFT_Get_Face_yMax(m_Face); - bbox.top = FXFT_Get_Face_yMin(m_Face); - bbox.right = FXFT_Get_Face_xMax(m_Face); - } else { - bbox.left = FXFT_Get_Face_xMin(m_Face) * 1000 / em; - bbox.top = FXFT_Get_Face_yMin(m_Face) * 1000 / em; - bbox.right = FXFT_Get_Face_xMax(m_Face) * 1000 / em; - bbox.bottom = FXFT_Get_Face_yMax(m_Face) * 1000 / em; - } - return TRUE; +FX_BOOL CFX_Font::GetBBox(FX_RECT& bbox) { + if (m_Face == NULL) { + return FALSE; + } + int em = FXFT_Get_Face_UnitsPerEM(m_Face); + if (em == 0) { + bbox.left = FXFT_Get_Face_xMin(m_Face); + bbox.bottom = FXFT_Get_Face_yMax(m_Face); + bbox.top = FXFT_Get_Face_yMin(m_Face); + bbox.right = FXFT_Get_Face_xMax(m_Face); + } else { + bbox.left = FXFT_Get_Face_xMin(m_Face) * 1000 / em; + bbox.top = FXFT_Get_Face_yMin(m_Face) * 1000 / em; + bbox.right = FXFT_Get_Face_xMax(m_Face) * 1000 / em; + bbox.bottom = FXFT_Get_Face_yMax(m_Face) * 1000 / em; + } + return TRUE; } -int CFX_Font::GetHeight() -{ - if (m_Face == NULL) { - return 0; - } - int height = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_Height(m_Face)); - return height; +int CFX_Font::GetHeight() { + if (m_Face == NULL) { + return 0; + } + int height = + EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_Height(m_Face)); + return height; } -int CFX_Font::GetMaxAdvanceWidth() -{ - if (m_Face == NULL) { - return 0; - } - int width = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_MaxAdvanceWidth(m_Face)); - return width; +int CFX_Font::GetMaxAdvanceWidth() { + if (m_Face == NULL) { + return 0; + } + int width = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), + FXFT_Get_Face_MaxAdvanceWidth(m_Face)); + return width; } -int CFX_Font::GetULPos() -{ - if (m_Face == NULL) { - return 0; - } - int pos = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_UnderLinePosition(m_Face)); - return pos; +int CFX_Font::GetULPos() { + if (m_Face == NULL) { + return 0; + } + int pos = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), + FXFT_Get_Face_UnderLinePosition(m_Face)); + return pos; } -int CFX_Font::GetULthickness() -{ - if (m_Face == NULL) { - return 0; - } - int thickness = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_UnderLineThickness(m_Face)); - return thickness; +int CFX_Font::GetULthickness() { + if (m_Face == NULL) { + return 0; + } + int thickness = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), + FXFT_Get_Face_UnderLineThickness(m_Face)); + return thickness; } -CFX_UnicodeEncoding::CFX_UnicodeEncoding(CFX_Font* pFont) -{ - m_pFont = pFont; +CFX_UnicodeEncoding::CFX_UnicodeEncoding(CFX_Font* pFont) { + m_pFont = pFont; } -FX_DWORD CFX_UnicodeEncoding::GlyphFromCharCode(FX_DWORD charcode) -{ - FXFT_Face face = m_pFont->GetFace(); - if (!face) { - return charcode; - } - if (FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE) == 0) { - return FXFT_Get_Char_Index(face, charcode); - } - if (m_pFont->m_pSubstFont && m_pFont->m_pSubstFont->m_Charset == 2) { - FX_DWORD index = 0; - if (FXFT_Select_Charmap(face, FXFT_ENCODING_MS_SYMBOL) == 0) { - index = FXFT_Get_Char_Index(face, charcode); - } - if (!index && !FXFT_Select_Charmap(face, FXFT_ENCODING_APPLE_ROMAN)) { - return FXFT_Get_Char_Index(face, charcode); - } - } +FX_DWORD CFX_UnicodeEncoding::GlyphFromCharCode(FX_DWORD charcode) { + FXFT_Face face = m_pFont->GetFace(); + if (!face) { return charcode; -} -FX_DWORD CFX_UnicodeEncoding::GlyphFromCharCodeEx(FX_DWORD charcode, int encoding) -{ - FXFT_Face face = m_pFont->GetFace(); - if (!face) { - return charcode; - } - if (encoding == ENCODING_UNICODE) { - return GlyphFromCharCode(charcode); + } + if (FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE) == 0) { + return FXFT_Get_Char_Index(face, charcode); + } + if (m_pFont->m_pSubstFont && m_pFont->m_pSubstFont->m_Charset == 2) { + FX_DWORD index = 0; + if (FXFT_Select_Charmap(face, FXFT_ENCODING_MS_SYMBOL) == 0) { + index = FXFT_Get_Char_Index(face, charcode); } - int nmaps = FXFT_Get_Face_CharmapCount(m_pFont->m_Face); - int i = 0; - while (i < nmaps) { - int encoding = FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[i++]); - if (encoding != FXFT_ENCODING_UNICODE) { - FXFT_Select_Charmap(face, encoding); - break; - } + if (!index && !FXFT_Select_Charmap(face, FXFT_ENCODING_APPLE_ROMAN)) { + return FXFT_Get_Char_Index(face, charcode); } - return FXFT_Get_Char_Index(face, charcode); + } + return charcode; +} +FX_DWORD CFX_UnicodeEncoding::GlyphFromCharCodeEx(FX_DWORD charcode, + int encoding) { + FXFT_Face face = m_pFont->GetFace(); + if (!face) { + return charcode; + } + if (encoding == ENCODING_UNICODE) { + return GlyphFromCharCode(charcode); + } + int nmaps = FXFT_Get_Face_CharmapCount(m_pFont->m_Face); + int i = 0; + while (i < nmaps) { + int encoding = FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[i++]); + if (encoding != FXFT_ENCODING_UNICODE) { + FXFT_Select_Charmap(face, encoding); + break; + } + } + return FXFT_Get_Char_Index(face, charcode); } -IFX_FontEncoding* FXGE_CreateUnicodeEncoding(CFX_Font* pFont) -{ - return new CFX_UnicodeEncoding(pFont); +IFX_FontEncoding* FXGE_CreateUnicodeEncoding(CFX_Font* pFont) { + return new CFX_UnicodeEncoding(pFont); } diff --git a/core/src/fxge/ge/fx_ge_fontmap.cpp b/core/src/fxge/ge/fx_ge_fontmap.cpp index 495d95c8d7..cd2195829f 100644 --- a/core/src/fxge/ge/fx_ge_fontmap.cpp +++ b/core/src/fxge/ge/fx_ge_fontmap.cpp @@ -9,147 +9,150 @@ #include "../../../include/fxge/fx_ge.h" #include "../../../include/fxge/fx_freetype.h" #include "text_int.h" -#define GET_TT_SHORT(w) (FX_WORD)(((w)[0] << 8) | (w)[1]) -#define GET_TT_LONG(w) (FX_DWORD)(((w)[0] << 24) | ((w)[1] << 16) | ((w)[2] << 8) | (w)[3]) -CFX_SubstFont::CFX_SubstFont() -{ - m_ExtHandle = NULL; - m_Charset = 0; - m_SubstFlags = 0; - m_Weight = 0; - m_ItalicAngle = 0; - m_bSubstOfCJK = FALSE; - m_WeightCJK = 0; - m_bItlicCJK = FALSE; +#define GET_TT_SHORT(w) (FX_WORD)(((w)[0] << 8) | (w)[1]) +#define GET_TT_LONG(w) \ + (FX_DWORD)(((w)[0] << 24) | ((w)[1] << 16) | ((w)[2] << 8) | (w)[3]) +CFX_SubstFont::CFX_SubstFont() { + m_ExtHandle = NULL; + m_Charset = 0; + m_SubstFlags = 0; + m_Weight = 0; + m_ItalicAngle = 0; + m_bSubstOfCJK = FALSE; + m_WeightCJK = 0; + m_bItlicCJK = FALSE; } -CTTFontDesc::~CTTFontDesc() -{ - if (m_Type == 1) { - if (m_SingleFace.m_pFace) { - FXFT_Done_Face(m_SingleFace.m_pFace); - } - } else if (m_Type == 2) { - for (int i = 0; i < 16; i ++) - if (m_TTCFace.m_pFaces[i]) { - FXFT_Done_Face(m_TTCFace.m_pFaces[i]); - } - } - if (m_pFontData) { - FX_Free(m_pFontData); - } +CTTFontDesc::~CTTFontDesc() { + if (m_Type == 1) { + if (m_SingleFace.m_pFace) { + FXFT_Done_Face(m_SingleFace.m_pFace); + } + } else if (m_Type == 2) { + for (int i = 0; i < 16; i++) + if (m_TTCFace.m_pFaces[i]) { + FXFT_Done_Face(m_TTCFace.m_pFaces[i]); + } + } + if (m_pFontData) { + FX_Free(m_pFontData); + } } -FX_BOOL CTTFontDesc::ReleaseFace(FXFT_Face face) -{ - if (m_Type == 1) { - if (m_SingleFace.m_pFace != face) { - return FALSE; - } - } else if (m_Type == 2) { - int i; - for (i = 0; i < 16; i ++) - if (m_TTCFace.m_pFaces[i] == face) { - break; - } - if (i == 16) { - return FALSE; - } +FX_BOOL CTTFontDesc::ReleaseFace(FXFT_Face face) { + if (m_Type == 1) { + if (m_SingleFace.m_pFace != face) { + return FALSE; } - m_RefCount --; - if (m_RefCount) { - return FALSE; - } - delete this; - return TRUE; + } else if (m_Type == 2) { + int i; + for (i = 0; i < 16; i++) + if (m_TTCFace.m_pFaces[i] == face) { + break; + } + if (i == 16) { + return FALSE; + } + } + m_RefCount--; + if (m_RefCount) { + return FALSE; + } + delete this; + return TRUE; } -CFX_FontMgr::CFX_FontMgr() : m_FTLibrary(nullptr) -{ - m_pBuiltinMapper = new CFX_FontMapper(this); - FXSYS_memset(m_ExternalFonts, 0, sizeof m_ExternalFonts); +CFX_FontMgr::CFX_FontMgr() : m_FTLibrary(nullptr) { + m_pBuiltinMapper = new CFX_FontMapper(this); + FXSYS_memset(m_ExternalFonts, 0, sizeof m_ExternalFonts); } -CFX_FontMgr::~CFX_FontMgr() -{ - delete m_pBuiltinMapper; - FreeCache(); - if (m_FTLibrary) { - FXFT_Done_FreeType(m_FTLibrary); - } +CFX_FontMgr::~CFX_FontMgr() { + delete m_pBuiltinMapper; + FreeCache(); + if (m_FTLibrary) { + FXFT_Done_FreeType(m_FTLibrary); + } } -void CFX_FontMgr::InitFTLibrary() -{ - if (m_FTLibrary == NULL) { - FXFT_Init_FreeType(&m_FTLibrary); - } +void CFX_FontMgr::InitFTLibrary() { + if (m_FTLibrary == NULL) { + FXFT_Init_FreeType(&m_FTLibrary); + } } -void CFX_FontMgr::FreeCache() -{ - FX_POSITION pos = m_FaceMap.GetStartPosition(); - while(pos) { - CFX_ByteString Key; - CTTFontDesc* face; - m_FaceMap.GetNextAssoc(pos, Key, (void*&)face); - delete face; - } - m_FaceMap.RemoveAll(); +void CFX_FontMgr::FreeCache() { + FX_POSITION pos = m_FaceMap.GetStartPosition(); + while (pos) { + CFX_ByteString Key; + CTTFontDesc* face; + m_FaceMap.GetNextAssoc(pos, Key, (void*&)face); + delete face; + } + m_FaceMap.RemoveAll(); } -void CFX_FontMgr::SetSystemFontInfo(IFX_SystemFontInfo* pFontInfo) -{ - m_pBuiltinMapper->SetSystemFontInfo(pFontInfo); +void CFX_FontMgr::SetSystemFontInfo(IFX_SystemFontInfo* pFontInfo) { + m_pBuiltinMapper->SetSystemFontInfo(pFontInfo); } -FXFT_Face CFX_FontMgr::FindSubstFont(const CFX_ByteString& face_name, FX_BOOL bTrueType, - FX_DWORD flags, int weight, int italic_angle, int CharsetCP, CFX_SubstFont* pSubstFont) -{ - if (!m_FTLibrary) { - FXFT_Init_FreeType(&m_FTLibrary); - } - return m_pBuiltinMapper->FindSubstFont(face_name, bTrueType, flags, weight, italic_angle, CharsetCP, pSubstFont); +FXFT_Face CFX_FontMgr::FindSubstFont(const CFX_ByteString& face_name, + FX_BOOL bTrueType, + FX_DWORD flags, + int weight, + int italic_angle, + int CharsetCP, + CFX_SubstFont* pSubstFont) { + if (!m_FTLibrary) { + FXFT_Init_FreeType(&m_FTLibrary); + } + return m_pBuiltinMapper->FindSubstFont(face_name, bTrueType, flags, weight, + italic_angle, CharsetCP, pSubstFont); } FXFT_Face CFX_FontMgr::GetCachedFace(const CFX_ByteString& face_name, - int weight, FX_BOOL bItalic, uint8_t*& pFontData) -{ - CFX_ByteString key(face_name); - key += ','; - key += CFX_ByteString::FormatInteger(weight); - key += bItalic ? 'I' : 'N'; - CTTFontDesc* pFontDesc = NULL; - m_FaceMap.Lookup(key, (void*&)pFontDesc); - if(pFontDesc) { - pFontData = pFontDesc->m_pFontData; - pFontDesc->m_RefCount ++; - return pFontDesc->m_SingleFace.m_pFace; - } - return NULL; + int weight, + FX_BOOL bItalic, + uint8_t*& pFontData) { + CFX_ByteString key(face_name); + key += ','; + key += CFX_ByteString::FormatInteger(weight); + key += bItalic ? 'I' : 'N'; + CTTFontDesc* pFontDesc = NULL; + m_FaceMap.Lookup(key, (void*&)pFontDesc); + if (pFontDesc) { + pFontData = pFontDesc->m_pFontData; + pFontDesc->m_RefCount++; + return pFontDesc->m_SingleFace.m_pFace; + } + return NULL; } FXFT_Face CFX_FontMgr::AddCachedFace(const CFX_ByteString& face_name, - int weight, FX_BOOL bItalic, uint8_t* pData, FX_DWORD size, int face_index) -{ - CTTFontDesc* pFontDesc = new CTTFontDesc; - pFontDesc->m_Type = 1; - pFontDesc->m_SingleFace.m_pFace = NULL; - pFontDesc->m_SingleFace.m_bBold = weight; - pFontDesc->m_SingleFace.m_bItalic = bItalic; - pFontDesc->m_pFontData = pData; - pFontDesc->m_RefCount = 1; - FXFT_Library library; - if (m_FTLibrary == NULL) { - FXFT_Init_FreeType(&m_FTLibrary); - } - library = m_FTLibrary; - int ret = FXFT_New_Memory_Face(library, pData, size, face_index, &pFontDesc->m_SingleFace.m_pFace); - if (ret) { - delete pFontDesc; - return NULL; - } - ret = FXFT_Set_Pixel_Sizes(pFontDesc->m_SingleFace.m_pFace, 64, 64); - if (ret) { - delete pFontDesc; - return NULL; - } - CFX_ByteString key(face_name); - key += ','; - key += CFX_ByteString::FormatInteger(weight); - key += bItalic ? 'I' : 'N'; - m_FaceMap.SetAt(key, pFontDesc); - return pFontDesc->m_SingleFace.m_pFace; + int weight, + FX_BOOL bItalic, + uint8_t* pData, + FX_DWORD size, + int face_index) { + CTTFontDesc* pFontDesc = new CTTFontDesc; + pFontDesc->m_Type = 1; + pFontDesc->m_SingleFace.m_pFace = NULL; + pFontDesc->m_SingleFace.m_bBold = weight; + pFontDesc->m_SingleFace.m_bItalic = bItalic; + pFontDesc->m_pFontData = pData; + pFontDesc->m_RefCount = 1; + FXFT_Library library; + if (m_FTLibrary == NULL) { + FXFT_Init_FreeType(&m_FTLibrary); + } + library = m_FTLibrary; + int ret = FXFT_New_Memory_Face(library, pData, size, face_index, + &pFontDesc->m_SingleFace.m_pFace); + if (ret) { + delete pFontDesc; + return NULL; + } + ret = FXFT_Set_Pixel_Sizes(pFontDesc->m_SingleFace.m_pFace, 64, 64); + if (ret) { + delete pFontDesc; + return NULL; + } + CFX_ByteString key(face_name); + key += ','; + key += CFX_ByteString::FormatInteger(weight); + key += bItalic ? 'I' : 'N'; + m_FaceMap.SetAt(key, pFontDesc); + return pFontDesc->m_SingleFace.m_pFace; } const FX_CHAR* const g_Base14FontNames[14] = { "Courier", @@ -168,10 +171,9 @@ const FX_CHAR* const g_Base14FontNames[14] = { "ZapfDingbats", }; const struct _AltFontName { - const FX_CHAR* m_pName; - int m_Index; -} -g_AltFontNames[] = { + const FX_CHAR* m_pName; + int m_Index; +} g_AltFontNames[] = { {"Arial", 4}, {"Arial,Bold", 5}, {"Arial,BoldItalic", 6}, @@ -263,144 +265,149 @@ g_AltFontNames[] = { {"ZapfDingbats", 13}, }; extern "C" { - static int compareString(const void* key, const void* element) - { - return FXSYS_stricmp((const FX_CHAR*)key, ((_AltFontName*)element)->m_pName); - } +static int compareString(const void* key, const void* element) { + return FXSYS_stricmp((const FX_CHAR*)key, ((_AltFontName*)element)->m_pName); } -int _PDF_GetStandardFontName(CFX_ByteString& name) -{ - _AltFontName* found = (_AltFontName*)FXSYS_bsearch(name.c_str(), g_AltFontNames, - sizeof g_AltFontNames / sizeof (_AltFontName), sizeof (_AltFontName), compareString); - if (found == NULL) { - return -1; - } - name = g_Base14FontNames[found->m_Index]; - return found->m_Index; } -int GetTTCIndex(const uint8_t* pFontData, FX_DWORD ttc_size, FX_DWORD font_offset) -{ - int face_index = 0; - const uint8_t* p = pFontData + 8; - FX_DWORD nfont = GET_TT_LONG(p); - FX_DWORD index; - for (index = 0; index < nfont; index ++) { - p = pFontData + 12 + index * 4; - if (GET_TT_LONG(p) == font_offset) { - break; - } - } - if(index >= nfont) { - face_index = 0; - } else { - face_index = index; - } - return face_index; +int _PDF_GetStandardFontName(CFX_ByteString& name) { + _AltFontName* found = + (_AltFontName*)FXSYS_bsearch(name.c_str(), g_AltFontNames, + sizeof g_AltFontNames / sizeof(_AltFontName), + sizeof(_AltFontName), compareString); + if (found == NULL) { + return -1; + } + name = g_Base14FontNames[found->m_Index]; + return found->m_Index; } -FXFT_Face CFX_FontMgr::GetCachedTTCFace(int ttc_size, FX_DWORD checksum, - int font_offset, uint8_t*& pFontData) -{ - CFX_ByteString key; - key.Format("%d:%d", ttc_size, checksum); - CTTFontDesc* pFontDesc = NULL; - m_FaceMap.Lookup(key, (void*&)pFontDesc); - if (pFontDesc == NULL) { - return NULL; - } - pFontData = pFontDesc->m_pFontData; - pFontDesc->m_RefCount ++; - int face_index = GetTTCIndex(pFontDesc->m_pFontData, ttc_size, font_offset); - if (pFontDesc->m_TTCFace.m_pFaces[face_index] == NULL) { - pFontDesc->m_TTCFace.m_pFaces[face_index] = GetFixedFace(pFontDesc->m_pFontData, ttc_size, face_index); - } - return pFontDesc->m_TTCFace.m_pFaces[face_index]; +int GetTTCIndex(const uint8_t* pFontData, + FX_DWORD ttc_size, + FX_DWORD font_offset) { + int face_index = 0; + const uint8_t* p = pFontData + 8; + FX_DWORD nfont = GET_TT_LONG(p); + FX_DWORD index; + for (index = 0; index < nfont; index++) { + p = pFontData + 12 + index * 4; + if (GET_TT_LONG(p) == font_offset) { + break; + } + } + if (index >= nfont) { + face_index = 0; + } else { + face_index = index; + } + return face_index; } -FXFT_Face CFX_FontMgr::AddCachedTTCFace(int ttc_size, FX_DWORD checksum, - uint8_t* pData, FX_DWORD size, int font_offset) -{ - CFX_ByteString key; - key.Format("%d:%d", ttc_size, checksum); - CTTFontDesc* pFontDesc = new CTTFontDesc; - pFontDesc->m_Type = 2; - pFontDesc->m_pFontData = pData; - for (int i = 0; i < 16; i ++) { - pFontDesc->m_TTCFace.m_pFaces[i] = NULL; - } - pFontDesc->m_RefCount ++; - key.Format("%d:%d", ttc_size, checksum); - m_FaceMap.SetAt(key, pFontDesc); - int face_index = GetTTCIndex(pFontDesc->m_pFontData, ttc_size, font_offset); - pFontDesc->m_TTCFace.m_pFaces[face_index] = GetFixedFace(pFontDesc->m_pFontData, ttc_size, face_index); - return pFontDesc->m_TTCFace.m_pFaces[face_index]; +FXFT_Face CFX_FontMgr::GetCachedTTCFace(int ttc_size, + FX_DWORD checksum, + int font_offset, + uint8_t*& pFontData) { + CFX_ByteString key; + key.Format("%d:%d", ttc_size, checksum); + CTTFontDesc* pFontDesc = NULL; + m_FaceMap.Lookup(key, (void*&)pFontDesc); + if (pFontDesc == NULL) { + return NULL; + } + pFontData = pFontDesc->m_pFontData; + pFontDesc->m_RefCount++; + int face_index = GetTTCIndex(pFontDesc->m_pFontData, ttc_size, font_offset); + if (pFontDesc->m_TTCFace.m_pFaces[face_index] == NULL) { + pFontDesc->m_TTCFace.m_pFaces[face_index] = + GetFixedFace(pFontDesc->m_pFontData, ttc_size, face_index); + } + return pFontDesc->m_TTCFace.m_pFaces[face_index]; } -FXFT_Face CFX_FontMgr::GetFixedFace(const uint8_t* pData, FX_DWORD size, int face_index) -{ - FXFT_Library library; - if (m_FTLibrary == NULL) { - FXFT_Init_FreeType(&m_FTLibrary); - } - library = m_FTLibrary; - FXFT_Face face = NULL; - int ret = FXFT_New_Memory_Face(library, pData, size, face_index, &face); - if (ret) { - return NULL; - } - ret = FXFT_Set_Pixel_Sizes(face, 64, 64); - if (ret) { - return NULL; - } - return face; +FXFT_Face CFX_FontMgr::AddCachedTTCFace(int ttc_size, + FX_DWORD checksum, + uint8_t* pData, + FX_DWORD size, + int font_offset) { + CFX_ByteString key; + key.Format("%d:%d", ttc_size, checksum); + CTTFontDesc* pFontDesc = new CTTFontDesc; + pFontDesc->m_Type = 2; + pFontDesc->m_pFontData = pData; + for (int i = 0; i < 16; i++) { + pFontDesc->m_TTCFace.m_pFaces[i] = NULL; + } + pFontDesc->m_RefCount++; + key.Format("%d:%d", ttc_size, checksum); + m_FaceMap.SetAt(key, pFontDesc); + int face_index = GetTTCIndex(pFontDesc->m_pFontData, ttc_size, font_offset); + pFontDesc->m_TTCFace.m_pFaces[face_index] = + GetFixedFace(pFontDesc->m_pFontData, ttc_size, face_index); + return pFontDesc->m_TTCFace.m_pFaces[face_index]; } -FXFT_Face CFX_FontMgr::GetFileFace(const FX_CHAR* filename, int face_index) -{ - FXFT_Library library; - if (m_FTLibrary == NULL) { - FXFT_Init_FreeType(&m_FTLibrary); - } - library = m_FTLibrary; - FXFT_Face face = NULL; - int ret = FXFT_New_Face(library, filename, face_index, &face); - if (ret) { - return NULL; - } - ret = FXFT_Set_Pixel_Sizes(face, 64, 64); - if (ret) { - return NULL; - } - return face; +FXFT_Face CFX_FontMgr::GetFixedFace(const uint8_t* pData, + FX_DWORD size, + int face_index) { + FXFT_Library library; + if (m_FTLibrary == NULL) { + FXFT_Init_FreeType(&m_FTLibrary); + } + library = m_FTLibrary; + FXFT_Face face = NULL; + int ret = FXFT_New_Memory_Face(library, pData, size, face_index, &face); + if (ret) { + return NULL; + } + ret = FXFT_Set_Pixel_Sizes(face, 64, 64); + if (ret) { + return NULL; + } + return face; } -void CFX_FontMgr::ReleaseFace(FXFT_Face face) -{ - if (face == NULL) { - return; - } - FX_POSITION pos = m_FaceMap.GetStartPosition(); - while(pos) { - CFX_ByteString Key; - CTTFontDesc* ttface; - m_FaceMap.GetNextAssoc(pos, Key, (void*&)ttface); - if (ttface->ReleaseFace(face)) { - m_FaceMap.RemoveKey(Key); - } - } +FXFT_Face CFX_FontMgr::GetFileFace(const FX_CHAR* filename, int face_index) { + FXFT_Library library; + if (m_FTLibrary == NULL) { + FXFT_Init_FreeType(&m_FTLibrary); + } + library = m_FTLibrary; + FXFT_Face face = NULL; + int ret = FXFT_New_Face(library, filename, face_index, &face); + if (ret) { + return NULL; + } + ret = FXFT_Set_Pixel_Sizes(face, 64, 64); + if (ret) { + return NULL; + } + return face; +} +void CFX_FontMgr::ReleaseFace(FXFT_Face face) { + if (face == NULL) { + return; + } + FX_POSITION pos = m_FaceMap.GetStartPosition(); + while (pos) { + CFX_ByteString Key; + CTTFontDesc* ttface; + m_FaceMap.GetNextAssoc(pos, Key, (void*&)ttface); + if (ttface->ReleaseFace(face)) { + m_FaceMap.RemoveKey(Key); + } + } } extern "C" { - extern const unsigned char g_FoxitFixedItalicFontData [18746]; - extern const unsigned char g_FoxitFixedFontData [17597]; - extern const unsigned char g_FoxitSansItalicFontData [16339]; - extern const unsigned char g_FoxitSansFontData [15025]; - extern const unsigned char g_FoxitSerifItalicFontData [21227]; - extern const unsigned char g_FoxitSerifFontData [19469]; - extern const unsigned char g_FoxitFixedBoldItalicFontData [19151]; - extern const unsigned char g_FoxitFixedBoldFontData [18055]; - extern const unsigned char g_FoxitSansBoldItalicFontData [16418]; - extern const unsigned char g_FoxitSansBoldFontData [16344]; - extern const unsigned char g_FoxitSerifBoldItalicFontData [20733]; - extern const unsigned char g_FoxitSerifBoldFontData [19395]; - extern const unsigned char g_FoxitSymbolFontData[16729]; - extern const unsigned char g_FoxitDingbatsFontData[29513]; - extern const unsigned char g_FoxitSerifMMFontData[113417]; - extern const unsigned char g_FoxitSansMMFontData[66919]; +extern const unsigned char g_FoxitFixedItalicFontData[18746]; +extern const unsigned char g_FoxitFixedFontData[17597]; +extern const unsigned char g_FoxitSansItalicFontData[16339]; +extern const unsigned char g_FoxitSansFontData[15025]; +extern const unsigned char g_FoxitSerifItalicFontData[21227]; +extern const unsigned char g_FoxitSerifFontData[19469]; +extern const unsigned char g_FoxitFixedBoldItalicFontData[19151]; +extern const unsigned char g_FoxitFixedBoldFontData[18055]; +extern const unsigned char g_FoxitSansBoldItalicFontData[16418]; +extern const unsigned char g_FoxitSansBoldFontData[16344]; +extern const unsigned char g_FoxitSerifBoldItalicFontData[20733]; +extern const unsigned char g_FoxitSerifBoldFontData[19395]; +extern const unsigned char g_FoxitSymbolFontData[16729]; +extern const unsigned char g_FoxitDingbatsFontData[29513]; +extern const unsigned char g_FoxitSerifMMFontData[113417]; +extern const unsigned char g_FoxitSansMMFontData[66919]; }; const FoxitFonts g_FoxitFonts[14] = { {g_FoxitFixedFontData, 17597}, @@ -418,1094 +425,1089 @@ const FoxitFonts g_FoxitFonts[14] = { {g_FoxitSymbolFontData, 16729}, {g_FoxitDingbatsFontData, 29513}, }; -void _FPDFAPI_GetInternalFontData(int id, const uint8_t*& data, FX_DWORD& size) -{ - CFX_GEModule::Get()->GetFontMgr()->GetStandardFont(data, size, id); +void _FPDFAPI_GetInternalFontData(int id, + const uint8_t*& data, + FX_DWORD& size) { + CFX_GEModule::Get()->GetFontMgr()->GetStandardFont(data, size, id); } -FX_BOOL CFX_FontMgr::GetStandardFont(const uint8_t*& pFontData, FX_DWORD& size, int index) -{ - if (index > 15 || index < 0) { - return FALSE; - } - { - if (index >= 14) { - if (index == 14) { - pFontData = g_FoxitSerifMMFontData; - size = 113417; - } else { - pFontData = g_FoxitSansMMFontData; - size = 66919; - } - } else { - pFontData = g_FoxitFonts[index].m_pFontData; - size = g_FoxitFonts[index].m_dwSize; - } +FX_BOOL CFX_FontMgr::GetStandardFont(const uint8_t*& pFontData, + FX_DWORD& size, + int index) { + if (index > 15 || index < 0) { + return FALSE; + } + { + if (index >= 14) { + if (index == 14) { + pFontData = g_FoxitSerifMMFontData; + size = 113417; + } else { + pFontData = g_FoxitSansMMFontData; + size = 66919; + } + } else { + pFontData = g_FoxitFonts[index].m_pFontData; + size = g_FoxitFonts[index].m_dwSize; } - return TRUE; + } + return TRUE; } CFX_FontMapper::CFX_FontMapper(CFX_FontMgr* mgr) - : m_pFontInfo(nullptr), - m_bListLoaded(FALSE), - m_pFontEnumerator(nullptr), - m_pFontMgr(mgr) -{ - FXSYS_memset(m_FoxitFaces, 0, sizeof m_FoxitFaces); - m_MMFaces[0] = m_MMFaces[1] = NULL; + : m_pFontInfo(nullptr), + m_bListLoaded(FALSE), + m_pFontEnumerator(nullptr), + m_pFontMgr(mgr) { + FXSYS_memset(m_FoxitFaces, 0, sizeof m_FoxitFaces); + m_MMFaces[0] = m_MMFaces[1] = NULL; } -CFX_FontMapper::~CFX_FontMapper() -{ - for (int i = 0; i < 14; i ++) - if (m_FoxitFaces[i]) { - FXFT_Done_Face(m_FoxitFaces[i]); - } - if (m_MMFaces[0]) { - FXFT_Done_Face(m_MMFaces[0]); - } - if (m_MMFaces[1]) { - FXFT_Done_Face(m_MMFaces[1]); - } - if (m_pFontInfo) { - m_pFontInfo->Release(); - } +CFX_FontMapper::~CFX_FontMapper() { + for (int i = 0; i < 14; i++) + if (m_FoxitFaces[i]) { + FXFT_Done_Face(m_FoxitFaces[i]); + } + if (m_MMFaces[0]) { + FXFT_Done_Face(m_MMFaces[0]); + } + if (m_MMFaces[1]) { + FXFT_Done_Face(m_MMFaces[1]); + } + if (m_pFontInfo) { + m_pFontInfo->Release(); + } } -void CFX_FontMapper::SetSystemFontInfo(IFX_SystemFontInfo* pFontInfo) -{ - if (pFontInfo == NULL) { - return; - } - if (m_pFontInfo) { - m_pFontInfo->Release(); - } - m_pFontInfo = pFontInfo; +void CFX_FontMapper::SetSystemFontInfo(IFX_SystemFontInfo* pFontInfo) { + if (pFontInfo == NULL) { + return; + } + if (m_pFontInfo) { + m_pFontInfo->Release(); + } + m_pFontInfo = pFontInfo; } -static CFX_ByteString _TT_NormalizeName(const FX_CHAR* family) -{ - CFX_ByteString norm(family, -1); - norm.Remove(' '); - norm.Remove('-'); - norm.Remove(','); - int pos = norm.Find('+'); - if (pos > 0) { - norm = norm.Left(pos); - } - norm.MakeLower(); - return norm; +static CFX_ByteString _TT_NormalizeName(const FX_CHAR* family) { + CFX_ByteString norm(family, -1); + norm.Remove(' '); + norm.Remove('-'); + norm.Remove(','); + int pos = norm.Find('+'); + if (pos > 0) { + norm = norm.Left(pos); + } + norm.MakeLower(); + return norm; } -CFX_ByteString _FPDF_GetNameFromTT(const uint8_t* name_table, FX_DWORD name_id) -{ - const uint8_t* ptr = name_table + 2; - int name_count = GET_TT_SHORT(ptr); - int string_offset = GET_TT_SHORT(ptr + 2); - const uint8_t* string_ptr = name_table + string_offset; - ptr += 4; - for (int i = 0; i < name_count; i ++) { - if (GET_TT_SHORT(ptr + 6) == name_id && GET_TT_SHORT(ptr) == 1 && GET_TT_SHORT(ptr + 2) == 0) { - return CFX_ByteStringC(string_ptr + GET_TT_SHORT(ptr + 10), GET_TT_SHORT(ptr + 8)); - } - ptr += 12; - } - return CFX_ByteString(); +CFX_ByteString _FPDF_GetNameFromTT(const uint8_t* name_table, + FX_DWORD name_id) { + const uint8_t* ptr = name_table + 2; + int name_count = GET_TT_SHORT(ptr); + int string_offset = GET_TT_SHORT(ptr + 2); + const uint8_t* string_ptr = name_table + string_offset; + ptr += 4; + for (int i = 0; i < name_count; i++) { + if (GET_TT_SHORT(ptr + 6) == name_id && GET_TT_SHORT(ptr) == 1 && + GET_TT_SHORT(ptr + 2) == 0) { + return CFX_ByteStringC(string_ptr + GET_TT_SHORT(ptr + 10), + GET_TT_SHORT(ptr + 8)); + } + ptr += 12; + } + return CFX_ByteString(); } -static CFX_ByteString _FPDF_ReadStringFromFile(FXSYS_FILE* pFile, FX_DWORD size) -{ - CFX_ByteString buffer; - if (!FXSYS_fread(buffer.GetBuffer(size), size, 1, pFile)) { - return CFX_ByteString(); - } - buffer.ReleaseBuffer(size); - return buffer; -} -CFX_ByteString _FPDF_LoadTableFromTT(FXSYS_FILE* pFile, const uint8_t* pTables, FX_DWORD nTables, FX_DWORD tag) -{ - for (FX_DWORD i = 0; i < nTables; i ++) { - const uint8_t* p = pTables + i * 16; - if (GET_TT_LONG(p) == tag) { - FX_DWORD offset = GET_TT_LONG(p + 8); - FX_DWORD size = GET_TT_LONG(p + 12); - FXSYS_fseek(pFile, offset, FXSYS_SEEK_SET); - return _FPDF_ReadStringFromFile(pFile, size); - } - } +static CFX_ByteString _FPDF_ReadStringFromFile(FXSYS_FILE* pFile, + FX_DWORD size) { + CFX_ByteString buffer; + if (!FXSYS_fread(buffer.GetBuffer(size), size, 1, pFile)) { return CFX_ByteString(); + } + buffer.ReleaseBuffer(size); + return buffer; } -CFX_ByteString _FPDF_LoadTableFromTTStreamFile(IFX_FileStream* pFile, const uint8_t* pTables, FX_DWORD nTables, FX_DWORD tag) -{ - for (FX_DWORD i = 0; i < nTables; i ++) { - const uint8_t* p = pTables + i * 16; - if (GET_TT_LONG(p) == tag) { - FX_DWORD offset = GET_TT_LONG(p + 8); - FX_DWORD size = GET_TT_LONG(p + 12); - CFX_ByteString buffer; - if (!pFile->ReadBlock(buffer.GetBuffer(size), offset, size)) { - return CFX_ByteString(); - } - buffer.ReleaseBuffer(size); - return buffer; - } - } - return CFX_ByteString(); +CFX_ByteString _FPDF_LoadTableFromTT(FXSYS_FILE* pFile, + const uint8_t* pTables, + FX_DWORD nTables, + FX_DWORD tag) { + for (FX_DWORD i = 0; i < nTables; i++) { + const uint8_t* p = pTables + i * 16; + if (GET_TT_LONG(p) == tag) { + FX_DWORD offset = GET_TT_LONG(p + 8); + FX_DWORD size = GET_TT_LONG(p + 12); + FXSYS_fseek(pFile, offset, FXSYS_SEEK_SET); + return _FPDF_ReadStringFromFile(pFile, size); + } + } + return CFX_ByteString(); } -CFX_ByteString CFX_FontMapper::GetPSNameFromTT(void* hFont) -{ - if (m_pFontInfo == NULL) { - CFX_ByteString(); - } - CFX_ByteString result; - FX_DWORD size = m_pFontInfo->GetFontData(hFont, 0x6e616d65, NULL, 0); - if (size) { - uint8_t* buffer = FX_Alloc(uint8_t, size); - m_pFontInfo->GetFontData(hFont, 0x6e616d65, buffer, size); - result = _FPDF_GetNameFromTT(buffer, 6); - FX_Free(buffer); +CFX_ByteString _FPDF_LoadTableFromTTStreamFile(IFX_FileStream* pFile, + const uint8_t* pTables, + FX_DWORD nTables, + FX_DWORD tag) { + for (FX_DWORD i = 0; i < nTables; i++) { + const uint8_t* p = pTables + i * 16; + if (GET_TT_LONG(p) == tag) { + FX_DWORD offset = GET_TT_LONG(p + 8); + FX_DWORD size = GET_TT_LONG(p + 12); + CFX_ByteString buffer; + if (!pFile->ReadBlock(buffer.GetBuffer(size), offset, size)) { + return CFX_ByteString(); + } + buffer.ReleaseBuffer(size); + return buffer; } - return result; + } + return CFX_ByteString(); } -void CFX_FontMapper::AddInstalledFont(const CFX_ByteString& name, int charset) -{ - if (m_pFontInfo == NULL) { - return; - } - if (m_CharsetArray.Find((FX_DWORD)charset) == -1) { - m_CharsetArray.Add((FX_DWORD)charset); - m_FaceArray.Add(name); - } - if (name == m_LastFamily) { - return; - } - const uint8_t* ptr = name; - FX_BOOL bLocalized = FALSE; - for (int i = 0; i < name.GetLength(); i ++) - if (ptr[i] > 0x80) { - bLocalized = TRUE; - break; - } - if (bLocalized) { - void* hFont = m_pFontInfo->GetFont(name); - if (hFont == NULL) { - int iExact; - hFont = m_pFontInfo->MapFont(0, 0, FXFONT_DEFAULT_CHARSET, 0, name, iExact); - if (hFont == NULL) { - return; - } - } - CFX_ByteString new_name = GetPSNameFromTT(hFont); - if (!new_name.IsEmpty()) { - new_name.Insert(0, ' '); - m_InstalledTTFonts.Add(new_name); - } - m_pFontInfo->DeleteFont(hFont); - } - m_InstalledTTFonts.Add(name); - m_LastFamily = name; +CFX_ByteString CFX_FontMapper::GetPSNameFromTT(void* hFont) { + if (m_pFontInfo == NULL) { + CFX_ByteString(); + } + CFX_ByteString result; + FX_DWORD size = m_pFontInfo->GetFontData(hFont, 0x6e616d65, NULL, 0); + if (size) { + uint8_t* buffer = FX_Alloc(uint8_t, size); + m_pFontInfo->GetFontData(hFont, 0x6e616d65, buffer, size); + result = _FPDF_GetNameFromTT(buffer, 6); + FX_Free(buffer); + } + return result; } -void CFX_FontMapper::LoadInstalledFonts() -{ - if (m_pFontInfo == NULL) { - return; - } - if (m_bListLoaded) { +void CFX_FontMapper::AddInstalledFont(const CFX_ByteString& name, int charset) { + if (m_pFontInfo == NULL) { + return; + } + if (m_CharsetArray.Find((FX_DWORD)charset) == -1) { + m_CharsetArray.Add((FX_DWORD)charset); + m_FaceArray.Add(name); + } + if (name == m_LastFamily) { + return; + } + const uint8_t* ptr = name; + FX_BOOL bLocalized = FALSE; + for (int i = 0; i < name.GetLength(); i++) + if (ptr[i] > 0x80) { + bLocalized = TRUE; + break; + } + if (bLocalized) { + void* hFont = m_pFontInfo->GetFont(name); + if (hFont == NULL) { + int iExact; + hFont = + m_pFontInfo->MapFont(0, 0, FXFONT_DEFAULT_CHARSET, 0, name, iExact); + if (hFont == NULL) { return; + } } - if (m_bListLoaded) { - return; + CFX_ByteString new_name = GetPSNameFromTT(hFont); + if (!new_name.IsEmpty()) { + new_name.Insert(0, ' '); + m_InstalledTTFonts.Add(new_name); } - m_pFontInfo->EnumFontList(this); - m_bListLoaded = TRUE; + m_pFontInfo->DeleteFont(hFont); + } + m_InstalledTTFonts.Add(name); + m_LastFamily = name; } -CFX_ByteString CFX_FontMapper::MatchInstalledFonts(const CFX_ByteString& norm_name) -{ - LoadInstalledFonts(); - int i; - for (i = m_InstalledTTFonts.GetSize() - 1; i >= 0; i --) { - CFX_ByteString norm1 = _TT_NormalizeName(m_InstalledTTFonts[i]); - if (norm1 == norm_name) { - break; - } - } - if (i < 0) { - return CFX_ByteString(); - } - CFX_ByteString match = m_InstalledTTFonts[i]; - if (match[0] == ' ') { - match = m_InstalledTTFonts[i + 1]; - } - return match; +void CFX_FontMapper::LoadInstalledFonts() { + if (m_pFontInfo == NULL) { + return; + } + if (m_bListLoaded) { + return; + } + if (m_bListLoaded) { + return; + } + m_pFontInfo->EnumFontList(this); + m_bListLoaded = TRUE; +} +CFX_ByteString CFX_FontMapper::MatchInstalledFonts( + const CFX_ByteString& norm_name) { + LoadInstalledFonts(); + int i; + for (i = m_InstalledTTFonts.GetSize() - 1; i >= 0; i--) { + CFX_ByteString norm1 = _TT_NormalizeName(m_InstalledTTFonts[i]); + if (norm1 == norm_name) { + break; + } + } + if (i < 0) { + return CFX_ByteString(); + } + CFX_ByteString match = m_InstalledTTFonts[i]; + if (match[0] == ' ') { + match = m_InstalledTTFonts[i + 1]; + } + return match; } typedef struct _CHARSET_MAP_ { - uint8_t charset; - FX_WORD codepage; + uint8_t charset; + FX_WORD codepage; } CHARSET_MAP; static const CHARSET_MAP g_Codepage2CharsetTable[] = { - { 1 , 0 }, - { 2 , 42 }, - { 254, 437 }, - { 255, 850 }, - { 222, 874 }, - { 128, 932 }, - { 134, 936 }, - { 129, 949 }, - { 136, 950 }, - { 238, 1250 }, - { 204, 1251 }, - { 0, 1252 }, - { 161, 1253 }, - { 162, 1254 }, - { 177, 1255 }, - { 178, 1256 }, - { 186, 1257 }, - { 163, 1258 }, - { 130, 1361 }, - { 77, 10000 }, - { 78, 10001 }, - { 79, 10003 }, - { 80, 10008 }, - { 81, 10002 }, - { 83, 10005 }, - { 84, 10004 }, - { 85, 10006 }, - { 86, 10081 }, - { 87, 10021 }, - { 88, 10029 }, - { 89, 10007 }, + {1, 0}, {2, 42}, {254, 437}, {255, 850}, {222, 874}, + {128, 932}, {134, 936}, {129, 949}, {136, 950}, {238, 1250}, + {204, 1251}, {0, 1252}, {161, 1253}, {162, 1254}, {177, 1255}, + {178, 1256}, {186, 1257}, {163, 1258}, {130, 1361}, {77, 10000}, + {78, 10001}, {79, 10003}, {80, 10008}, {81, 10002}, {83, 10005}, + {84, 10004}, {85, 10006}, {86, 10081}, {87, 10021}, {88, 10029}, + {89, 10007}, }; -uint8_t _GetCharsetFromCodePage(FX_WORD codepage) -{ - int32_t iEnd = sizeof(g_Codepage2CharsetTable) / sizeof(CHARSET_MAP) - 1; - FXSYS_assert(iEnd >= 0); - int32_t iStart = 0, iMid; - do { - iMid = (iStart + iEnd) / 2; - const CHARSET_MAP & cp = g_Codepage2CharsetTable[iMid]; - if (codepage == cp.codepage) { - return cp.charset; - } - if (codepage < cp.codepage) { - iEnd = iMid - 1; - } else { - iStart = iMid + 1; - } - } while (iStart <= iEnd); - return 1; -} -FX_DWORD _GetCodePageRangeFromCharset(int charset) -{ - if (charset == FXFONT_EASTEUROPE_CHARSET) { - return 1 << 1; - } - if (charset == FXFONT_GREEK_CHARSET) { - return 1 << 3; - } - if (charset == FXFONT_TURKISH_CHARSET) { - return 1 << 4; - } - if (charset == FXFONT_HEBREW_CHARSET) { - return 1 << 5; - } - if (charset == FXFONT_ARABIC_CHARSET) { - return 1 << 6; - } - if (charset == FXFONT_BALTIC_CHARSET) { - return 1 << 7; - } - if (charset == FXFONT_THAI_CHARSET) { - return 1 << 16; - } - if (charset == FXFONT_SHIFTJIS_CHARSET) { - return 1 << 17; - } - if (charset == FXFONT_GB2312_CHARSET) { - return 1 << 18; - } - if (charset == FXFONT_CHINESEBIG5_CHARSET) { - return 1 << 20; - } - if (charset == FXFONT_HANGEUL_CHARSET) { - return 1 << 19; - } - if (charset == FXFONT_SYMBOL_CHARSET) { - return 1 << 31; +uint8_t _GetCharsetFromCodePage(FX_WORD codepage) { + int32_t iEnd = sizeof(g_Codepage2CharsetTable) / sizeof(CHARSET_MAP) - 1; + FXSYS_assert(iEnd >= 0); + int32_t iStart = 0, iMid; + do { + iMid = (iStart + iEnd) / 2; + const CHARSET_MAP& cp = g_Codepage2CharsetTable[iMid]; + if (codepage == cp.codepage) { + return cp.charset; + } + if (codepage < cp.codepage) { + iEnd = iMid - 1; + } else { + iStart = iMid + 1; } - return 1 << 21; + } while (iStart <= iEnd); + return 1; } -FXFT_Face CFX_FontMapper::UseInternalSubst(CFX_SubstFont* pSubstFont, int iBaseFont, int italic_angle, int weight, int picthfamily) -{ - if (iBaseFont < 12) { - if (m_FoxitFaces[iBaseFont]) { - return m_FoxitFaces[iBaseFont]; - } - const uint8_t* pFontData = NULL; - FX_DWORD size = 0; - if (m_pFontMgr->GetStandardFont(pFontData, size, iBaseFont)) { - m_FoxitFaces[iBaseFont] = m_pFontMgr->GetFixedFace(pFontData, size, 0); - return m_FoxitFaces[iBaseFont]; - } - } - pSubstFont->m_SubstFlags |= FXFONT_SUBST_MM; - pSubstFont->m_ItalicAngle = italic_angle; - if (weight) { - pSubstFont->m_Weight = weight; - } - if (picthfamily & FXFONT_FF_ROMAN) { - pSubstFont->m_Weight = pSubstFont->m_Weight * 4 / 5; - pSubstFont->m_Family = "Chrome Serif"; - if (m_MMFaces[1]) { - return m_MMFaces[1]; - } - const uint8_t* pFontData = NULL; - FX_DWORD size; - m_pFontMgr->GetStandardFont(pFontData, size, 14); - m_MMFaces[1] = m_pFontMgr->GetFixedFace(pFontData, size, 0); - return m_MMFaces[1]; - } - pSubstFont->m_Family = "Chrome Sans"; - if (m_MMFaces[0]) { - return m_MMFaces[0]; +FX_DWORD _GetCodePageRangeFromCharset(int charset) { + if (charset == FXFONT_EASTEUROPE_CHARSET) { + return 1 << 1; + } + if (charset == FXFONT_GREEK_CHARSET) { + return 1 << 3; + } + if (charset == FXFONT_TURKISH_CHARSET) { + return 1 << 4; + } + if (charset == FXFONT_HEBREW_CHARSET) { + return 1 << 5; + } + if (charset == FXFONT_ARABIC_CHARSET) { + return 1 << 6; + } + if (charset == FXFONT_BALTIC_CHARSET) { + return 1 << 7; + } + if (charset == FXFONT_THAI_CHARSET) { + return 1 << 16; + } + if (charset == FXFONT_SHIFTJIS_CHARSET) { + return 1 << 17; + } + if (charset == FXFONT_GB2312_CHARSET) { + return 1 << 18; + } + if (charset == FXFONT_CHINESEBIG5_CHARSET) { + return 1 << 20; + } + if (charset == FXFONT_HANGEUL_CHARSET) { + return 1 << 19; + } + if (charset == FXFONT_SYMBOL_CHARSET) { + return 1 << 31; + } + return 1 << 21; +} +FXFT_Face CFX_FontMapper::UseInternalSubst(CFX_SubstFont* pSubstFont, + int iBaseFont, + int italic_angle, + int weight, + int picthfamily) { + if (iBaseFont < 12) { + if (m_FoxitFaces[iBaseFont]) { + return m_FoxitFaces[iBaseFont]; } const uint8_t* pFontData = NULL; FX_DWORD size = 0; - m_pFontMgr->GetStandardFont(pFontData, size, 15); - m_MMFaces[0] = m_pFontMgr->GetFixedFace(pFontData, size, 0); + if (m_pFontMgr->GetStandardFont(pFontData, size, iBaseFont)) { + m_FoxitFaces[iBaseFont] = m_pFontMgr->GetFixedFace(pFontData, size, 0); + return m_FoxitFaces[iBaseFont]; + } + } + pSubstFont->m_SubstFlags |= FXFONT_SUBST_MM; + pSubstFont->m_ItalicAngle = italic_angle; + if (weight) { + pSubstFont->m_Weight = weight; + } + if (picthfamily & FXFONT_FF_ROMAN) { + pSubstFont->m_Weight = pSubstFont->m_Weight * 4 / 5; + pSubstFont->m_Family = "Chrome Serif"; + if (m_MMFaces[1]) { + return m_MMFaces[1]; + } + const uint8_t* pFontData = NULL; + FX_DWORD size; + m_pFontMgr->GetStandardFont(pFontData, size, 14); + m_MMFaces[1] = m_pFontMgr->GetFixedFace(pFontData, size, 0); + return m_MMFaces[1]; + } + pSubstFont->m_Family = "Chrome Sans"; + if (m_MMFaces[0]) { return m_MMFaces[0]; + } + const uint8_t* pFontData = NULL; + FX_DWORD size = 0; + m_pFontMgr->GetStandardFont(pFontData, size, 15); + m_MMFaces[0] = m_pFontMgr->GetFixedFace(pFontData, size, 0); + return m_MMFaces[0]; } const struct _AltFontFamily { - const FX_CHAR* m_pFontName; - const FX_CHAR* m_pFontFamily; -} -g_AltFontFamilies[] = { + const FX_CHAR* m_pFontName; + const FX_CHAR* m_pFontFamily; +} g_AltFontFamilies[] = { {"AGaramondPro", "Adobe Garamond Pro"}, {"BankGothicBT-Medium", "BankGothic Md BT"}, {"ForteMT", "Forte"}, }; extern "C" { - static int compareFontFamilyString(const void* key, const void* element) - { - CFX_ByteString str_key((const FX_CHAR*)key); - if (str_key.Find(((_AltFontFamily*)element)->m_pFontName) != -1) { - return 0; - } - return FXSYS_stricmp((const FX_CHAR*)key, ((_AltFontFamily*)element)->m_pFontName); - } +static int compareFontFamilyString(const void* key, const void* element) { + CFX_ByteString str_key((const FX_CHAR*)key); + if (str_key.Find(((_AltFontFamily*)element)->m_pFontName) != -1) { + return 0; + } + return FXSYS_stricmp((const FX_CHAR*)key, + ((_AltFontFamily*)element)->m_pFontName); } -#define FX_FONT_STYLE_None 0x00 -#define FX_FONT_STYLE_Bold 0x01 -#define FX_FONT_STYLE_Italic 0x02 -#define FX_FONT_STYLE_BoldBold 0x04 -static CFX_ByteString _GetFontFamily(CFX_ByteString fontName, int nStyle) -{ - if (fontName.Find("Script") >= 0) { - if ((nStyle & FX_FONT_STYLE_Bold) == FX_FONT_STYLE_Bold) { - fontName = "ScriptMTBold"; - } else if (fontName.Find("Palace") >= 0) { - fontName = "PalaceScriptMT"; - } else if (fontName.Find("French") >= 0) { - fontName = "FrenchScriptMT"; - } else if (fontName.Find("FreeStyle") >= 0) { - fontName = "FreeStyleScript"; - } - return fontName; - } - _AltFontFamily* found = (_AltFontFamily*)FXSYS_bsearch(fontName.c_str(), g_AltFontFamilies, - sizeof g_AltFontFamilies / sizeof (_AltFontFamily), sizeof (_AltFontFamily), compareFontFamilyString); - if (found == NULL) { - return fontName; - } - return found->m_pFontFamily; +} +#define FX_FONT_STYLE_None 0x00 +#define FX_FONT_STYLE_Bold 0x01 +#define FX_FONT_STYLE_Italic 0x02 +#define FX_FONT_STYLE_BoldBold 0x04 +static CFX_ByteString _GetFontFamily(CFX_ByteString fontName, int nStyle) { + if (fontName.Find("Script") >= 0) { + if ((nStyle & FX_FONT_STYLE_Bold) == FX_FONT_STYLE_Bold) { + fontName = "ScriptMTBold"; + } else if (fontName.Find("Palace") >= 0) { + fontName = "PalaceScriptMT"; + } else if (fontName.Find("French") >= 0) { + fontName = "FrenchScriptMT"; + } else if (fontName.Find("FreeStyle") >= 0) { + fontName = "FreeStyleScript"; + } + return fontName; + } + _AltFontFamily* found = (_AltFontFamily*)FXSYS_bsearch( + fontName.c_str(), g_AltFontFamilies, + sizeof g_AltFontFamilies / sizeof(_AltFontFamily), sizeof(_AltFontFamily), + compareFontFamilyString); + if (found == NULL) { + return fontName; + } + return found->m_pFontFamily; }; typedef struct _FX_FontStyle { - const FX_CHAR* style; - int32_t len; + const FX_CHAR* style; + int32_t len; } FX_FontStyle; const FX_FontStyle g_FontStyles[] = { - { "Bold", 4 }, - { "Italic", 6 }, - { "BoldItalic", 10 }, - { "Reg", 3 }, - { "Regular", 7 }, + {"Bold", 4}, {"Italic", 6}, {"BoldItalic", 10}, {"Reg", 3}, {"Regular", 7}, }; -CFX_ByteString ParseStyle(const FX_CHAR* pStyle, int iLen, int iIndex) -{ - CFX_ByteTextBuf buf; - if (!iLen || iLen <= iIndex) { - return buf.GetByteString(); - } - while (iIndex < iLen) { - if (pStyle[iIndex] == ',') { - break; - } - buf.AppendChar(pStyle[iIndex]); - ++iIndex; - } +CFX_ByteString ParseStyle(const FX_CHAR* pStyle, int iLen, int iIndex) { + CFX_ByteTextBuf buf; + if (!iLen || iLen <= iIndex) { return buf.GetByteString(); + } + while (iIndex < iLen) { + if (pStyle[iIndex] == ',') { + break; + } + buf.AppendChar(pStyle[iIndex]); + ++iIndex; + } + return buf.GetByteString(); } -int32_t GetStyleType(const CFX_ByteString &bsStyle, FX_BOOL bRevert) -{ - int32_t iLen = bsStyle.GetLength(); - if (!iLen) { - return -1; - } - int iSize = sizeof(g_FontStyles) / sizeof(FX_FontStyle); - const FX_FontStyle *pStyle = NULL; - for (int i = iSize - 1; i >= 0; --i) { - pStyle = g_FontStyles + i; - if (!pStyle || pStyle->len > iLen) { - continue; - } - if (!bRevert) { - if (bsStyle.Left(pStyle->len).Compare(pStyle->style) == 0) { - return i; - } - } else { - if (bsStyle.Right(pStyle->len).Compare(pStyle->style) == 0) { - return i; - } - } - } +int32_t GetStyleType(const CFX_ByteString& bsStyle, FX_BOOL bRevert) { + int32_t iLen = bsStyle.GetLength(); + if (!iLen) { return -1; -} -FX_BOOL CheckSupportThirdPartFont(CFX_ByteString name, int &PitchFamily) -{ - if (name == FX_BSTRC("MyriadPro")) { - PitchFamily &= ~FXFONT_FF_ROMAN; - return TRUE; + } + int iSize = sizeof(g_FontStyles) / sizeof(FX_FontStyle); + const FX_FontStyle* pStyle = NULL; + for (int i = iSize - 1; i >= 0; --i) { + pStyle = g_FontStyles + i; + if (!pStyle || pStyle->len > iLen) { + continue; + } + if (!bRevert) { + if (bsStyle.Left(pStyle->len).Compare(pStyle->style) == 0) { + return i; + } + } else { + if (bsStyle.Right(pStyle->len).Compare(pStyle->style) == 0) { + return i; + } } - return FALSE; + } + return -1; } -FXFT_Face CFX_FontMapper::FindSubstFont(const CFX_ByteString& name, FX_BOOL bTrueType, FX_DWORD flags, - int weight, int italic_angle, int WindowCP, CFX_SubstFont* pSubstFont) -{ - if (!(flags & FXFONT_USEEXTERNATTR)) { - weight = FXFONT_FW_NORMAL; - italic_angle = 0; - } - CFX_ByteString SubstName = name; - SubstName.Remove(0x20); - if (bTrueType) { - if (name[0] == '@') { - SubstName = name.Mid(1); - } - } - _PDF_GetStandardFontName(SubstName); - if (SubstName == FX_BSTRC("Symbol") && !bTrueType) { - pSubstFont->m_Family = "Chrome Symbol"; - pSubstFont->m_Charset = FXFONT_SYMBOL_CHARSET; - pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; - if (m_FoxitFaces[12]) { - return m_FoxitFaces[12]; - } - const uint8_t* pFontData = NULL; - FX_DWORD size = 0; - m_pFontMgr->GetStandardFont(pFontData, size, 12); - m_FoxitFaces[12] = m_pFontMgr->GetFixedFace(pFontData, size, 0); - return m_FoxitFaces[12]; - } - if (SubstName == FX_BSTRC("ZapfDingbats")) { - pSubstFont->m_Family = "Chrome Dingbats"; - pSubstFont->m_Charset = FXFONT_SYMBOL_CHARSET; - pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; - if (m_FoxitFaces[13]) { - return m_FoxitFaces[13]; - } - const uint8_t* pFontData = NULL; - FX_DWORD size = 0; - m_pFontMgr->GetStandardFont(pFontData, size, 13); - m_FoxitFaces[13] = m_pFontMgr->GetFixedFace(pFontData, size, 0); - return m_FoxitFaces[13]; +FX_BOOL CheckSupportThirdPartFont(CFX_ByteString name, int& PitchFamily) { + if (name == FX_BSTRC("MyriadPro")) { + PitchFamily &= ~FXFONT_FF_ROMAN; + return TRUE; + } + return FALSE; +} +FXFT_Face CFX_FontMapper::FindSubstFont(const CFX_ByteString& name, + FX_BOOL bTrueType, + FX_DWORD flags, + int weight, + int italic_angle, + int WindowCP, + CFX_SubstFont* pSubstFont) { + if (!(flags & FXFONT_USEEXTERNATTR)) { + weight = FXFONT_FW_NORMAL; + italic_angle = 0; + } + CFX_ByteString SubstName = name; + SubstName.Remove(0x20); + if (bTrueType) { + if (name[0] == '@') { + SubstName = name.Mid(1); + } + } + _PDF_GetStandardFontName(SubstName); + if (SubstName == FX_BSTRC("Symbol") && !bTrueType) { + pSubstFont->m_Family = "Chrome Symbol"; + pSubstFont->m_Charset = FXFONT_SYMBOL_CHARSET; + pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; + if (m_FoxitFaces[12]) { + return m_FoxitFaces[12]; } - int iBaseFont = 0; - CFX_ByteString family, style; - FX_BOOL bHasComma = FALSE; - FX_BOOL bHasHypen = FALSE; - int find = SubstName.Find(FX_BSTRC(","), 0); - if (find >= 0) { - family = SubstName.Left(find); - _PDF_GetStandardFontName(family); - style = SubstName.Mid(find + 1); - bHasComma = TRUE; - } else { - family = SubstName; + const uint8_t* pFontData = NULL; + FX_DWORD size = 0; + m_pFontMgr->GetStandardFont(pFontData, size, 12); + m_FoxitFaces[12] = m_pFontMgr->GetFixedFace(pFontData, size, 0); + return m_FoxitFaces[12]; + } + if (SubstName == FX_BSTRC("ZapfDingbats")) { + pSubstFont->m_Family = "Chrome Dingbats"; + pSubstFont->m_Charset = FXFONT_SYMBOL_CHARSET; + pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; + if (m_FoxitFaces[13]) { + return m_FoxitFaces[13]; } - for (; iBaseFont < 12; iBaseFont ++) - if (family == CFX_ByteStringC(g_Base14FontNames[iBaseFont])) { - break; - } - int PitchFamily = 0; - FX_BOOL bItalic = FALSE; - FX_DWORD nStyle = 0; - FX_BOOL bStyleAvail = FALSE; - if (iBaseFont < 12) { - family = g_Base14FontNames[iBaseFont]; - if ((iBaseFont % 4) == 1 || (iBaseFont % 4) == 2) { - nStyle |= FX_FONT_STYLE_Bold; - } - if ((iBaseFont % 4) / 2) { - nStyle |= FX_FONT_STYLE_Italic; - } - if (iBaseFont < 4) { - PitchFamily |= FXFONT_FF_FIXEDPITCH; - } - if (iBaseFont >= 8) { - PitchFamily |= FXFONT_FF_ROMAN; - } - } else { - if (!bHasComma) { - find = family.ReverseFind('-'); - if (find >= 0) { - style = family.Mid(find + 1); - family = family.Left(find); - bHasHypen = TRUE; - } + const uint8_t* pFontData = NULL; + FX_DWORD size = 0; + m_pFontMgr->GetStandardFont(pFontData, size, 13); + m_FoxitFaces[13] = m_pFontMgr->GetFixedFace(pFontData, size, 0); + return m_FoxitFaces[13]; + } + int iBaseFont = 0; + CFX_ByteString family, style; + FX_BOOL bHasComma = FALSE; + FX_BOOL bHasHypen = FALSE; + int find = SubstName.Find(FX_BSTRC(","), 0); + if (find >= 0) { + family = SubstName.Left(find); + _PDF_GetStandardFontName(family); + style = SubstName.Mid(find + 1); + bHasComma = TRUE; + } else { + family = SubstName; + } + for (; iBaseFont < 12; iBaseFont++) + if (family == CFX_ByteStringC(g_Base14FontNames[iBaseFont])) { + break; + } + int PitchFamily = 0; + FX_BOOL bItalic = FALSE; + FX_DWORD nStyle = 0; + FX_BOOL bStyleAvail = FALSE; + if (iBaseFont < 12) { + family = g_Base14FontNames[iBaseFont]; + if ((iBaseFont % 4) == 1 || (iBaseFont % 4) == 2) { + nStyle |= FX_FONT_STYLE_Bold; + } + if ((iBaseFont % 4) / 2) { + nStyle |= FX_FONT_STYLE_Italic; + } + if (iBaseFont < 4) { + PitchFamily |= FXFONT_FF_FIXEDPITCH; + } + if (iBaseFont >= 8) { + PitchFamily |= FXFONT_FF_ROMAN; + } + } else { + if (!bHasComma) { + find = family.ReverseFind('-'); + if (find >= 0) { + style = family.Mid(find + 1); + family = family.Left(find); + bHasHypen = TRUE; + } + } + if (!bHasHypen) { + int nLen = family.GetLength(); + int32_t nRet = GetStyleType(family, TRUE); + if (nRet > -1) { + family = family.Left(nLen - g_FontStyles[nRet].len); + if (nRet == 0) { + nStyle |= FX_FONT_STYLE_Bold; } - if (!bHasHypen) { - int nLen = family.GetLength(); - int32_t nRet = GetStyleType(family, TRUE); - if (nRet > -1) { - family = family.Left(nLen - g_FontStyles[nRet].len); - if (nRet == 0) { - nStyle |= FX_FONT_STYLE_Bold; - } - if (nRet == 1) { - nStyle |= FX_FONT_STYLE_Italic; - } - if (nRet == 2) { - nStyle |= (FX_FONT_STYLE_Bold | FX_FONT_STYLE_Italic); - } - } + if (nRet == 1) { + nStyle |= FX_FONT_STYLE_Italic; } - if (flags & FXFONT_SERIF) { - PitchFamily |= FXFONT_FF_ROMAN; + if (nRet == 2) { + nStyle |= (FX_FONT_STYLE_Bold | FX_FONT_STYLE_Italic); } - if (flags & FXFONT_SCRIPT) { - PitchFamily |= FXFONT_FF_SCRIPT; + } + } + if (flags & FXFONT_SERIF) { + PitchFamily |= FXFONT_FF_ROMAN; + } + if (flags & FXFONT_SCRIPT) { + PitchFamily |= FXFONT_FF_SCRIPT; + } + if (flags & FXFONT_FIXED_PITCH) { + PitchFamily |= FXFONT_FF_FIXEDPITCH; + } + } + if (!style.IsEmpty()) { + int nLen = style.GetLength(); + const FX_CHAR* pStyle = style; + int i = 0; + FX_BOOL bFirstItem = TRUE; + CFX_ByteString buf; + while (i < nLen) { + buf = ParseStyle(pStyle, nLen, i); + int32_t nRet = GetStyleType(buf, FALSE); + if ((i && !bStyleAvail) || (!i && nRet < 0)) { + family = SubstName; + iBaseFont = 12; + break; + } else if (nRet >= 0) { + bStyleAvail = TRUE; + } + if (nRet == 0) { + if (nStyle & FX_FONT_STYLE_Bold) { + nStyle |= FX_FONT_STYLE_BoldBold; + } else { + nStyle |= FX_FONT_STYLE_Bold; } - if (flags & FXFONT_FIXED_PITCH) { - PitchFamily |= FXFONT_FF_FIXEDPITCH; + bFirstItem = FALSE; + } + if (nRet == 1) { + if (bFirstItem) { + nStyle |= FX_FONT_STYLE_Italic; + } else { + family = SubstName; + iBaseFont = 12; } - } - if (!style.IsEmpty()) { - int nLen = style.GetLength(); - const FX_CHAR* pStyle = style; - int i = 0; - FX_BOOL bFirstItem = TRUE; - CFX_ByteString buf; - while (i < nLen) { - buf = ParseStyle(pStyle, nLen, i); - int32_t nRet = GetStyleType(buf, FALSE); - if ((i && !bStyleAvail) || (!i && nRet < 0)) { - family = SubstName; - iBaseFont = 12; - break; - } else if (nRet >= 0) { - bStyleAvail = TRUE; - } - if (nRet == 0) { - if (nStyle & FX_FONT_STYLE_Bold) { - nStyle |= FX_FONT_STYLE_BoldBold; - } else { - nStyle |= FX_FONT_STYLE_Bold; - } - bFirstItem = FALSE; - } - if (nRet == 1) { - if (bFirstItem) { - nStyle |= FX_FONT_STYLE_Italic; - } else { - family = SubstName; - iBaseFont = 12; - } - break; - } - if (nRet == 2) { - nStyle |= FX_FONT_STYLE_Italic; - if (nStyle & FX_FONT_STYLE_Bold) { - nStyle |= FX_FONT_STYLE_BoldBold; - } else { - nStyle |= FX_FONT_STYLE_Bold; - } - bFirstItem = FALSE; - } - i += buf.GetLength() + 1; + break; + } + if (nRet == 2) { + nStyle |= FX_FONT_STYLE_Italic; + if (nStyle & FX_FONT_STYLE_Bold) { + nStyle |= FX_FONT_STYLE_BoldBold; + } else { + nStyle |= FX_FONT_STYLE_Bold; } - } - weight = weight ? weight : FXFONT_FW_NORMAL; - int old_weight = weight; - if (nStyle) { - weight = nStyle & FX_FONT_STYLE_BoldBold ? 900 : (nStyle & FX_FONT_STYLE_Bold ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL); - } - if (nStyle & FX_FONT_STYLE_Italic) { - bItalic = TRUE; - } - FX_BOOL bCJK = FALSE; - int iExact = 0; - int Charset = FXFONT_ANSI_CHARSET; - if (WindowCP) { - Charset = _GetCharsetFromCodePage(WindowCP); - } else if (iBaseFont == 12 && (flags & FXFONT_SYMBOLIC)) { - Charset = FXFONT_SYMBOL_CHARSET; - } - if (Charset == FXFONT_SHIFTJIS_CHARSET || Charset == FXFONT_GB2312_CHARSET || - Charset == FXFONT_HANGEUL_CHARSET || Charset == FXFONT_CHINESEBIG5_CHARSET) { - bCJK = TRUE; - } - if (m_pFontInfo == NULL) { - pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; - return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, PitchFamily); - } - family = _GetFontFamily(family, nStyle); - CFX_ByteString match = MatchInstalledFonts(_TT_NormalizeName(family)); - if (match.IsEmpty() && family != SubstName && (!bHasComma && (!bHasHypen || (bHasHypen && !bStyleAvail)))) { - match = MatchInstalledFonts(_TT_NormalizeName(SubstName)); - } - if (match.IsEmpty() && iBaseFont >= 12) { - if (!bCJK) { - if (!CheckSupportThirdPartFont(family, PitchFamily)) { - if (italic_angle != 0) { - bItalic = TRUE; - } else { - bItalic = FALSE; - } - weight = old_weight; - } + bFirstItem = FALSE; + } + i += buf.GetLength() + 1; + } + } + weight = weight ? weight : FXFONT_FW_NORMAL; + int old_weight = weight; + if (nStyle) { + weight = + nStyle & FX_FONT_STYLE_BoldBold + ? 900 + : (nStyle & FX_FONT_STYLE_Bold ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL); + } + if (nStyle & FX_FONT_STYLE_Italic) { + bItalic = TRUE; + } + FX_BOOL bCJK = FALSE; + int iExact = 0; + int Charset = FXFONT_ANSI_CHARSET; + if (WindowCP) { + Charset = _GetCharsetFromCodePage(WindowCP); + } else if (iBaseFont == 12 && (flags & FXFONT_SYMBOLIC)) { + Charset = FXFONT_SYMBOL_CHARSET; + } + if (Charset == FXFONT_SHIFTJIS_CHARSET || Charset == FXFONT_GB2312_CHARSET || + Charset == FXFONT_HANGEUL_CHARSET || + Charset == FXFONT_CHINESEBIG5_CHARSET) { + bCJK = TRUE; + } + if (m_pFontInfo == NULL) { + pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; + return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, + PitchFamily); + } + family = _GetFontFamily(family, nStyle); + CFX_ByteString match = MatchInstalledFonts(_TT_NormalizeName(family)); + if (match.IsEmpty() && family != SubstName && + (!bHasComma && (!bHasHypen || (bHasHypen && !bStyleAvail)))) { + match = MatchInstalledFonts(_TT_NormalizeName(SubstName)); + } + if (match.IsEmpty() && iBaseFont >= 12) { + if (!bCJK) { + if (!CheckSupportThirdPartFont(family, PitchFamily)) { + if (italic_angle != 0) { + bItalic = TRUE; } else { - pSubstFont->m_bSubstOfCJK = TRUE; - if (nStyle) { - pSubstFont->m_WeightCJK = weight; - } else { - pSubstFont->m_WeightCJK = FXFONT_FW_NORMAL; - } - if (nStyle & FX_FONT_STYLE_Italic) { - pSubstFont->m_bItlicCJK = TRUE; - } + bItalic = FALSE; } + weight = old_weight; + } } else { - italic_angle = 0; - weight = nStyle & FX_FONT_STYLE_BoldBold ? 900 : (nStyle & FX_FONT_STYLE_Bold ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL); + pSubstFont->m_bSubstOfCJK = TRUE; + if (nStyle) { + pSubstFont->m_WeightCJK = weight; + } else { + pSubstFont->m_WeightCJK = FXFONT_FW_NORMAL; + } + if (nStyle & FX_FONT_STYLE_Italic) { + pSubstFont->m_bItlicCJK = TRUE; + } + } + } else { + italic_angle = 0; + weight = + nStyle & FX_FONT_STYLE_BoldBold + ? 900 + : (nStyle & FX_FONT_STYLE_Bold ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL); + } + if (!match.IsEmpty() || iBaseFont < 12) { + pSubstFont->m_SubstFlags |= FXFONT_SUBST_EXACT; + if (!match.IsEmpty()) { + family = match; } - if (!match.IsEmpty() || iBaseFont < 12) { - pSubstFont->m_SubstFlags |= FXFONT_SUBST_EXACT; - if (!match.IsEmpty()) { - family = match; - } - if (iBaseFont < 12) { - if (nStyle && !(iBaseFont % 4)) { - if ((nStyle & 0x3) == 1) { - iBaseFont += 1; - } - if ((nStyle & 0x3) == 2) { - iBaseFont += 3; - } - if ((nStyle & 0x3) == 3) { - iBaseFont += 2; - } - } - if (m_pFontMgr->m_ExternalFonts[iBaseFont].m_pFontData) { - if (m_FoxitFaces[iBaseFont]) { - return m_FoxitFaces[iBaseFont]; - } - m_FoxitFaces[iBaseFont] = m_pFontMgr->GetFixedFace(m_pFontMgr->m_ExternalFonts[iBaseFont].m_pFontData, - m_pFontMgr->m_ExternalFonts[iBaseFont].m_dwSize, 0); - if (m_FoxitFaces[iBaseFont]) { - return m_FoxitFaces[iBaseFont]; - } - } else { - family = g_Base14FontNames[iBaseFont]; - } - pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; - } - } else { - if (flags & FXFONT_ITALIC) { - bItalic = TRUE; + if (iBaseFont < 12) { + if (nStyle && !(iBaseFont % 4)) { + if ((nStyle & 0x3) == 1) { + iBaseFont += 1; } - } - iExact = !match.IsEmpty(); - void* hFont = m_pFontInfo->MapFont(weight, bItalic, Charset, PitchFamily, family, iExact); - if (iExact) { - pSubstFont->m_SubstFlags |= FXFONT_SUBST_EXACT; - } - if (hFont == NULL) { - if (bCJK) { - if (italic_angle != 0) { - bItalic = TRUE; - } else { - bItalic = FALSE; - } - weight = old_weight; + if ((nStyle & 0x3) == 2) { + iBaseFont += 3; } - if (!match.IsEmpty()) { - hFont = m_pFontInfo->GetFont(match); - if (hFont == NULL) { - return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, PitchFamily); - } - } else { - if (Charset == FXFONT_SYMBOL_CHARSET) { -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ || _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_ - if (SubstName == FX_BSTRC("Symbol")) { - pSubstFont->m_Family = "Chrome Symbol"; - pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; - pSubstFont->m_Charset = FXFONT_SYMBOL_CHARSET; - if (m_FoxitFaces[12]) { - return m_FoxitFaces[12]; - } - const uint8_t* pFontData = NULL; - FX_DWORD size = 0; - m_pFontMgr->GetStandardFont(pFontData, size, 12); - m_FoxitFaces[12] = m_pFontMgr->GetFixedFace(pFontData, size, 0); - return m_FoxitFaces[12]; - } -#endif - pSubstFont->m_SubstFlags |= FXFONT_SUBST_NONSYMBOL; - return FindSubstFont(family, bTrueType, flags & ~FXFONT_SYMBOLIC, weight, italic_angle, 0, pSubstFont); - } - if (Charset == FXFONT_ANSI_CHARSET) { - pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; - return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, PitchFamily); - } - int index = m_CharsetArray.Find(Charset); - if (index < 0) { - return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, PitchFamily); - } - hFont = m_pFontInfo->GetFont(m_FaceArray[index]); + if ((nStyle & 0x3) == 3) { + iBaseFont += 2; } - } - pSubstFont->m_ExtHandle = m_pFontInfo->RetainFont(hFont); - if (hFont == NULL) { - return NULL; - } - m_pFontInfo->GetFaceName(hFont, SubstName); - if (Charset == FXFONT_DEFAULT_CHARSET) { - m_pFontInfo->GetFontCharset(hFont, Charset); - } - FX_DWORD ttc_size = m_pFontInfo->GetFontData(hFont, 0x74746366, NULL, 0); - FX_DWORD font_size = m_pFontInfo->GetFontData(hFont, 0, NULL, 0); - if(font_size == 0 && ttc_size == 0) { - m_pFontInfo->DeleteFont(hFont); - return NULL; - } - FXFT_Face face = NULL; - if (ttc_size) { - uint8_t temp[1024]; - m_pFontInfo->GetFontData(hFont, 0x74746366, temp, 1024); - FX_DWORD checksum = 0; - for (int i = 0; i < 256; i ++) { - checksum += ((FX_DWORD*)temp)[i]; + } + if (m_pFontMgr->m_ExternalFonts[iBaseFont].m_pFontData) { + if (m_FoxitFaces[iBaseFont]) { + return m_FoxitFaces[iBaseFont]; } - uint8_t* pFontData; - face = m_pFontMgr->GetCachedTTCFace(ttc_size, checksum, ttc_size - font_size, pFontData); - if (face == NULL) { - pFontData = FX_Alloc(uint8_t, ttc_size); - m_pFontInfo->GetFontData(hFont, 0x74746366, pFontData, ttc_size); - face = m_pFontMgr->AddCachedTTCFace(ttc_size, checksum, pFontData, ttc_size, - ttc_size - font_size); + m_FoxitFaces[iBaseFont] = m_pFontMgr->GetFixedFace( + m_pFontMgr->m_ExternalFonts[iBaseFont].m_pFontData, + m_pFontMgr->m_ExternalFonts[iBaseFont].m_dwSize, 0); + if (m_FoxitFaces[iBaseFont]) { + return m_FoxitFaces[iBaseFont]; } + } else { + family = g_Base14FontNames[iBaseFont]; + } + pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; + } + } else { + if (flags & FXFONT_ITALIC) { + bItalic = TRUE; + } + } + iExact = !match.IsEmpty(); + void* hFont = m_pFontInfo->MapFont(weight, bItalic, Charset, PitchFamily, + family, iExact); + if (iExact) { + pSubstFont->m_SubstFlags |= FXFONT_SUBST_EXACT; + } + if (hFont == NULL) { + if (bCJK) { + if (italic_angle != 0) { + bItalic = TRUE; + } else { + bItalic = FALSE; + } + weight = old_weight; + } + if (!match.IsEmpty()) { + hFont = m_pFontInfo->GetFont(match); + if (hFont == NULL) { + return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, + PitchFamily); + } } else { - uint8_t* pFontData; - face = m_pFontMgr->GetCachedFace(SubstName, weight, bItalic, pFontData); - if (face == NULL) { - pFontData = FX_Alloc(uint8_t, font_size); - m_pFontInfo->GetFontData(hFont, 0, pFontData, font_size); - face = m_pFontMgr->AddCachedFace(SubstName, weight, bItalic, pFontData, font_size, m_pFontInfo->GetFaceIndex(hFont)); + if (Charset == FXFONT_SYMBOL_CHARSET) { +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ || \ + _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_ + if (SubstName == FX_BSTRC("Symbol")) { + pSubstFont->m_Family = "Chrome Symbol"; + pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; + pSubstFont->m_Charset = FXFONT_SYMBOL_CHARSET; + if (m_FoxitFaces[12]) { + return m_FoxitFaces[12]; + } + const uint8_t* pFontData = NULL; + FX_DWORD size = 0; + m_pFontMgr->GetStandardFont(pFontData, size, 12); + m_FoxitFaces[12] = m_pFontMgr->GetFixedFace(pFontData, size, 0); + return m_FoxitFaces[12]; } - } +#endif + pSubstFont->m_SubstFlags |= FXFONT_SUBST_NONSYMBOL; + return FindSubstFont(family, bTrueType, flags & ~FXFONT_SYMBOLIC, + weight, italic_angle, 0, pSubstFont); + } + if (Charset == FXFONT_ANSI_CHARSET) { + pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; + return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, + PitchFamily); + } + int index = m_CharsetArray.Find(Charset); + if (index < 0) { + return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, + PitchFamily); + } + hFont = m_pFontInfo->GetFont(m_FaceArray[index]); + } + } + pSubstFont->m_ExtHandle = m_pFontInfo->RetainFont(hFont); + if (hFont == NULL) { + return NULL; + } + m_pFontInfo->GetFaceName(hFont, SubstName); + if (Charset == FXFONT_DEFAULT_CHARSET) { + m_pFontInfo->GetFontCharset(hFont, Charset); + } + FX_DWORD ttc_size = m_pFontInfo->GetFontData(hFont, 0x74746366, NULL, 0); + FX_DWORD font_size = m_pFontInfo->GetFontData(hFont, 0, NULL, 0); + if (font_size == 0 && ttc_size == 0) { + m_pFontInfo->DeleteFont(hFont); + return NULL; + } + FXFT_Face face = NULL; + if (ttc_size) { + uint8_t temp[1024]; + m_pFontInfo->GetFontData(hFont, 0x74746366, temp, 1024); + FX_DWORD checksum = 0; + for (int i = 0; i < 256; i++) { + checksum += ((FX_DWORD*)temp)[i]; + } + uint8_t* pFontData; + face = m_pFontMgr->GetCachedTTCFace(ttc_size, checksum, + ttc_size - font_size, pFontData); if (face == NULL) { - m_pFontInfo->DeleteFont(hFont); - return NULL; - } - pSubstFont->m_Family = SubstName; - pSubstFont->m_Charset = Charset; - FX_BOOL bNeedUpdateWeight = FALSE; - if (FXFT_Is_Face_Bold(face)) { - if (weight == FXFONT_FW_BOLD) { - bNeedUpdateWeight = FALSE; - } else { - bNeedUpdateWeight = TRUE; - } + pFontData = FX_Alloc(uint8_t, ttc_size); + m_pFontInfo->GetFontData(hFont, 0x74746366, pFontData, ttc_size); + face = m_pFontMgr->AddCachedTTCFace(ttc_size, checksum, pFontData, + ttc_size, ttc_size - font_size); + } + } else { + uint8_t* pFontData; + face = m_pFontMgr->GetCachedFace(SubstName, weight, bItalic, pFontData); + if (face == NULL) { + pFontData = FX_Alloc(uint8_t, font_size); + m_pFontInfo->GetFontData(hFont, 0, pFontData, font_size); + face = m_pFontMgr->AddCachedFace(SubstName, weight, bItalic, pFontData, + font_size, + m_pFontInfo->GetFaceIndex(hFont)); + } + } + if (face == NULL) { + m_pFontInfo->DeleteFont(hFont); + return NULL; + } + pSubstFont->m_Family = SubstName; + pSubstFont->m_Charset = Charset; + FX_BOOL bNeedUpdateWeight = FALSE; + if (FXFT_Is_Face_Bold(face)) { + if (weight == FXFONT_FW_BOLD) { + bNeedUpdateWeight = FALSE; } else { - if (weight == FXFONT_FW_NORMAL) { - bNeedUpdateWeight = FALSE; - } else { - bNeedUpdateWeight = TRUE; - } + bNeedUpdateWeight = TRUE; } - if (bNeedUpdateWeight) { - pSubstFont->m_Weight = weight; - } - if (bItalic && !FXFT_Is_Face_Italic(face)) { - if (italic_angle == 0) { - italic_angle = -12; - } else if (FXSYS_abs(italic_angle) < 5) { - italic_angle = 0; - } - pSubstFont->m_ItalicAngle = italic_angle; + } else { + if (weight == FXFONT_FW_NORMAL) { + bNeedUpdateWeight = FALSE; + } else { + bNeedUpdateWeight = TRUE; + } + } + if (bNeedUpdateWeight) { + pSubstFont->m_Weight = weight; + } + if (bItalic && !FXFT_Is_Face_Italic(face)) { + if (italic_angle == 0) { + italic_angle = -12; + } else if (FXSYS_abs(italic_angle) < 5) { + italic_angle = 0; } - m_pFontInfo->DeleteFont(hFont); - return face; + pSubstFont->m_ItalicAngle = italic_angle; + } + m_pFontInfo->DeleteFont(hFont); + return face; } extern "C" { - unsigned long _FTStreamRead(FXFT_Stream stream, unsigned long offset, - unsigned char* buffer, unsigned long count); - void _FTStreamClose(FXFT_Stream stream); +unsigned long _FTStreamRead(FXFT_Stream stream, + unsigned long offset, + unsigned char* buffer, + unsigned long count); +void _FTStreamClose(FXFT_Stream stream); }; -CFontFileFaceInfo::CFontFileFaceInfo() -{ - m_pFile = NULL; - m_Face = NULL; - m_Charsets = 0; - m_FileSize = 0; - m_FontOffset = 0; - m_Weight = 0; - m_bItalic = FALSE; - m_PitchFamily = 0; +CFontFileFaceInfo::CFontFileFaceInfo() { + m_pFile = NULL; + m_Face = NULL; + m_Charsets = 0; + m_FileSize = 0; + m_FontOffset = 0; + m_Weight = 0; + m_bItalic = FALSE; + m_PitchFamily = 0; } -CFontFileFaceInfo::~CFontFileFaceInfo() -{ - if (m_Face) { - FXFT_Done_Face(m_Face); - } - m_Face = NULL; +CFontFileFaceInfo::~CFontFileFaceInfo() { + if (m_Face) { + FXFT_Done_Face(m_Face); + } + m_Face = NULL; } -extern FX_BOOL _LoadFile(FXFT_Library library, FXFT_Face* Face, IFX_FileRead* pFile, FXFT_Stream* stream); +extern FX_BOOL _LoadFile(FXFT_Library library, + FXFT_Face* Face, + IFX_FileRead* pFile, + FXFT_Stream* stream); #if _FX_OS_ == _FX_ANDROID_ -IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault() -{ - return NULL; +IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault() { + return NULL; } #endif -CFX_FolderFontInfo::CFX_FolderFontInfo() -{ -} -CFX_FolderFontInfo::~CFX_FolderFontInfo() -{ - FX_POSITION pos = m_FontList.GetStartPosition(); - while (pos) { - CFX_ByteString key; - void* value; - m_FontList.GetNextAssoc(pos, key, value); - delete (CFontFaceInfo*)value; - } +CFX_FolderFontInfo::CFX_FolderFontInfo() {} +CFX_FolderFontInfo::~CFX_FolderFontInfo() { + FX_POSITION pos = m_FontList.GetStartPosition(); + while (pos) { + CFX_ByteString key; + void* value; + m_FontList.GetNextAssoc(pos, key, value); + delete (CFontFaceInfo*)value; + } } -void CFX_FolderFontInfo::AddPath(const CFX_ByteStringC& path) -{ - m_PathList.Add(path); +void CFX_FolderFontInfo::AddPath(const CFX_ByteStringC& path) { + m_PathList.Add(path); } -void CFX_FolderFontInfo::Release() -{ - delete this; +void CFX_FolderFontInfo::Release() { + delete this; } -FX_BOOL CFX_FolderFontInfo::EnumFontList(CFX_FontMapper* pMapper) -{ - m_pMapper = pMapper; - for (int i = 0; i < m_PathList.GetSize(); i ++) { - ScanPath(m_PathList[i]); - } - return TRUE; +FX_BOOL CFX_FolderFontInfo::EnumFontList(CFX_FontMapper* pMapper) { + m_pMapper = pMapper; + for (int i = 0; i < m_PathList.GetSize(); i++) { + ScanPath(m_PathList[i]); + } + return TRUE; } -void CFX_FolderFontInfo::ScanPath(CFX_ByteString& path) -{ - void* handle = FX_OpenFolder(path); - if (handle == NULL) { - return; - } - CFX_ByteString filename; - FX_BOOL bFolder; - while (FX_GetNextFile(handle, filename, bFolder)) { - if (bFolder) { - if (filename == "." || filename == "..") { - continue; - } - } else { - CFX_ByteString ext = filename.Right(4); - ext.MakeUpper(); - if (ext != ".TTF" && ext != ".OTF" && ext != ".TTC") { - continue; - } - } - CFX_ByteString fullpath = path; -#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ - fullpath += "\\"; +void CFX_FolderFontInfo::ScanPath(CFX_ByteString& path) { + void* handle = FX_OpenFolder(path); + if (handle == NULL) { + return; + } + CFX_ByteString filename; + FX_BOOL bFolder; + while (FX_GetNextFile(handle, filename, bFolder)) { + if (bFolder) { + if (filename == "." || filename == "..") { + continue; + } + } else { + CFX_ByteString ext = filename.Right(4); + ext.MakeUpper(); + if (ext != ".TTF" && ext != ".OTF" && ext != ".TTC") { + continue; + } + } + CFX_ByteString fullpath = path; +#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ + fullpath += "\\"; #else - fullpath += "/"; + fullpath += "/"; #endif - fullpath += filename; - if (bFolder) { - ScanPath(fullpath); - } else { - ScanFile(fullpath); - } - } - FX_CloseFolder(handle); -} -void CFX_FolderFontInfo::ScanFile(CFX_ByteString& path) -{ - FXSYS_FILE* pFile = FXSYS_fopen(path, "rb"); - if (pFile == NULL) { - return; - } - FXSYS_fseek(pFile, 0, FXSYS_SEEK_END); - FX_DWORD filesize = FXSYS_ftell(pFile); - uint8_t buffer[16]; - FXSYS_fseek(pFile, 0, FXSYS_SEEK_SET); - size_t readCnt = FXSYS_fread(buffer, 12, 1, pFile); - if (readCnt != 1) { - FXSYS_fclose(pFile); - return; - } - - if (GET_TT_LONG(buffer) == 0x74746366) { - FX_DWORD nFaces = GET_TT_LONG(buffer + 8); - if (nFaces > std::numeric_limits::max() / 4) { - FXSYS_fclose(pFile); - return; - } - FX_DWORD face_bytes = nFaces * 4; - uint8_t* offsets = FX_Alloc(uint8_t, face_bytes); - readCnt = FXSYS_fread(offsets, 1, face_bytes, pFile); - if (readCnt != face_bytes) { - FX_Free(offsets); - FXSYS_fclose(pFile); - return; - } - for (FX_DWORD i = 0; i < nFaces; i ++) { - uint8_t* p = offsets + i * 4; - ReportFace(path, pFile, filesize, GET_TT_LONG(p)); - } - FX_Free(offsets); + fullpath += filename; + if (bFolder) { + ScanPath(fullpath); } else { - ReportFace(path, pFile, filesize, 0); + ScanFile(fullpath); } - FXSYS_fclose(pFile); + } + FX_CloseFolder(handle); } -void CFX_FolderFontInfo::ReportFace(CFX_ByteString& path, FXSYS_FILE* pFile, FX_DWORD filesize, FX_DWORD offset) -{ - FXSYS_fseek(pFile, offset, FXSYS_SEEK_SET); - char buffer[16]; - if (!FXSYS_fread(buffer, 12, 1, pFile)) { - return; - } - FX_DWORD nTables = GET_TT_SHORT(buffer + 4); - CFX_ByteString tables = _FPDF_ReadStringFromFile(pFile, nTables * 16); - if (tables.IsEmpty()) { - return; - } - CFX_ByteString names = _FPDF_LoadTableFromTT(pFile, tables, nTables, 0x6e616d65); - CFX_ByteString facename = _FPDF_GetNameFromTT(names, 1); - CFX_ByteString style = _FPDF_GetNameFromTT(names, 2); - if (style != "Regular") { - facename += " " + style; - } - void* p; - if (m_FontList.Lookup(facename, p)) { - return; - } - CFontFaceInfo* pInfo = new CFontFaceInfo; - pInfo->m_FilePath = path; - pInfo->m_FaceName = facename; - pInfo->m_FontTables = tables; - pInfo->m_FontOffset = offset; - pInfo->m_FileSize = filesize; - pInfo->m_Charsets = 0; - CFX_ByteString os2 = _FPDF_LoadTableFromTT(pFile, tables, nTables, 0x4f532f32); - if (os2.GetLength() >= 86) { - const uint8_t* p = (const uint8_t*)os2 + 78; - FX_DWORD codepages = GET_TT_LONG(p); - if (codepages & (1 << 17)) { - m_pMapper->AddInstalledFont(facename, FXFONT_SHIFTJIS_CHARSET); - pInfo->m_Charsets |= CHARSET_FLAG_SHIFTJIS; - } - if (codepages & (1 << 18)) { - m_pMapper->AddInstalledFont(facename, FXFONT_GB2312_CHARSET); - pInfo->m_Charsets |= CHARSET_FLAG_GB; - } - if (codepages & (1 << 20)) { - m_pMapper->AddInstalledFont(facename, FXFONT_CHINESEBIG5_CHARSET); - pInfo->m_Charsets |= CHARSET_FLAG_BIG5; - } - if ((codepages & (1 << 19)) || (codepages & (1 << 21))) { - m_pMapper->AddInstalledFont(facename, FXFONT_HANGEUL_CHARSET); - pInfo->m_Charsets |= CHARSET_FLAG_KOREAN; - } - if (codepages & (1 << 31)) { - m_pMapper->AddInstalledFont(facename, FXFONT_SYMBOL_CHARSET); - pInfo->m_Charsets |= CHARSET_FLAG_SYMBOL; - } - } - m_pMapper->AddInstalledFont(facename, FXFONT_ANSI_CHARSET); - pInfo->m_Charsets |= CHARSET_FLAG_ANSI; - pInfo->m_Styles = 0; - if (style.Find(FX_BSTRC("Bold")) > -1) { - pInfo->m_Styles |= FXFONT_BOLD; - } - if (style.Find(FX_BSTRC("Italic")) > -1 || style.Find(FX_BSTRC("Oblique")) > -1) { - pInfo->m_Styles |= FXFONT_ITALIC; - } - if (facename.Find(FX_BSTRC("Serif")) > -1) { - pInfo->m_Styles |= FXFONT_SERIF; - } - m_FontList.SetAt(facename, pInfo); -} -void* CFX_FolderFontInfo::MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, const FX_CHAR* family, int& iExact) -{ - return NULL; +void CFX_FolderFontInfo::ScanFile(CFX_ByteString& path) { + FXSYS_FILE* pFile = FXSYS_fopen(path, "rb"); + if (pFile == NULL) { + return; + } + FXSYS_fseek(pFile, 0, FXSYS_SEEK_END); + FX_DWORD filesize = FXSYS_ftell(pFile); + uint8_t buffer[16]; + FXSYS_fseek(pFile, 0, FXSYS_SEEK_SET); + size_t readCnt = FXSYS_fread(buffer, 12, 1, pFile); + if (readCnt != 1) { + FXSYS_fclose(pFile); + return; + } + + if (GET_TT_LONG(buffer) == 0x74746366) { + FX_DWORD nFaces = GET_TT_LONG(buffer + 8); + if (nFaces > std::numeric_limits::max() / 4) { + FXSYS_fclose(pFile); + return; + } + FX_DWORD face_bytes = nFaces * 4; + uint8_t* offsets = FX_Alloc(uint8_t, face_bytes); + readCnt = FXSYS_fread(offsets, 1, face_bytes, pFile); + if (readCnt != face_bytes) { + FX_Free(offsets); + FXSYS_fclose(pFile); + return; + } + for (FX_DWORD i = 0; i < nFaces; i++) { + uint8_t* p = offsets + i * 4; + ReportFace(path, pFile, filesize, GET_TT_LONG(p)); + } + FX_Free(offsets); + } else { + ReportFace(path, pFile, filesize, 0); + } + FXSYS_fclose(pFile); } -void* CFX_FolderFontInfo::GetFont(const FX_CHAR* face) -{ - void* p; - if (!m_FontList.Lookup(face, p)) { - return NULL; - } - return p; +void CFX_FolderFontInfo::ReportFace(CFX_ByteString& path, + FXSYS_FILE* pFile, + FX_DWORD filesize, + FX_DWORD offset) { + FXSYS_fseek(pFile, offset, FXSYS_SEEK_SET); + char buffer[16]; + if (!FXSYS_fread(buffer, 12, 1, pFile)) { + return; + } + FX_DWORD nTables = GET_TT_SHORT(buffer + 4); + CFX_ByteString tables = _FPDF_ReadStringFromFile(pFile, nTables * 16); + if (tables.IsEmpty()) { + return; + } + CFX_ByteString names = + _FPDF_LoadTableFromTT(pFile, tables, nTables, 0x6e616d65); + CFX_ByteString facename = _FPDF_GetNameFromTT(names, 1); + CFX_ByteString style = _FPDF_GetNameFromTT(names, 2); + if (style != "Regular") { + facename += " " + style; + } + void* p; + if (m_FontList.Lookup(facename, p)) { + return; + } + CFontFaceInfo* pInfo = new CFontFaceInfo; + pInfo->m_FilePath = path; + pInfo->m_FaceName = facename; + pInfo->m_FontTables = tables; + pInfo->m_FontOffset = offset; + pInfo->m_FileSize = filesize; + pInfo->m_Charsets = 0; + CFX_ByteString os2 = + _FPDF_LoadTableFromTT(pFile, tables, nTables, 0x4f532f32); + if (os2.GetLength() >= 86) { + const uint8_t* p = (const uint8_t*)os2 + 78; + FX_DWORD codepages = GET_TT_LONG(p); + if (codepages & (1 << 17)) { + m_pMapper->AddInstalledFont(facename, FXFONT_SHIFTJIS_CHARSET); + pInfo->m_Charsets |= CHARSET_FLAG_SHIFTJIS; + } + if (codepages & (1 << 18)) { + m_pMapper->AddInstalledFont(facename, FXFONT_GB2312_CHARSET); + pInfo->m_Charsets |= CHARSET_FLAG_GB; + } + if (codepages & (1 << 20)) { + m_pMapper->AddInstalledFont(facename, FXFONT_CHINESEBIG5_CHARSET); + pInfo->m_Charsets |= CHARSET_FLAG_BIG5; + } + if ((codepages & (1 << 19)) || (codepages & (1 << 21))) { + m_pMapper->AddInstalledFont(facename, FXFONT_HANGEUL_CHARSET); + pInfo->m_Charsets |= CHARSET_FLAG_KOREAN; + } + if (codepages & (1 << 31)) { + m_pMapper->AddInstalledFont(facename, FXFONT_SYMBOL_CHARSET); + pInfo->m_Charsets |= CHARSET_FLAG_SYMBOL; + } + } + m_pMapper->AddInstalledFont(facename, FXFONT_ANSI_CHARSET); + pInfo->m_Charsets |= CHARSET_FLAG_ANSI; + pInfo->m_Styles = 0; + if (style.Find(FX_BSTRC("Bold")) > -1) { + pInfo->m_Styles |= FXFONT_BOLD; + } + if (style.Find(FX_BSTRC("Italic")) > -1 || + style.Find(FX_BSTRC("Oblique")) > -1) { + pInfo->m_Styles |= FXFONT_ITALIC; + } + if (facename.Find(FX_BSTRC("Serif")) > -1) { + pInfo->m_Styles |= FXFONT_SERIF; + } + m_FontList.SetAt(facename, pInfo); } -FX_DWORD CFX_FolderFontInfo::GetFontData(void* hFont, FX_DWORD table, uint8_t* buffer, FX_DWORD size) -{ - if (hFont == NULL) { - return 0; - } - CFontFaceInfo* pFont = (CFontFaceInfo*)hFont; - FXSYS_FILE* pFile = NULL; - if (size > 0) { - pFile = FXSYS_fopen(pFont->m_FilePath, "rb"); - if (pFile == NULL) { - return 0; - } - } - FX_DWORD datasize = 0; - FX_DWORD offset; - if (table == 0) { - datasize = pFont->m_FontOffset ? 0 : pFont->m_FileSize; - offset = 0; - } else if (table == 0x74746366) { - datasize = pFont->m_FontOffset ? pFont->m_FileSize : 0; - offset = 0; - } else { - FX_DWORD nTables = pFont->m_FontTables.GetLength() / 16; - for (FX_DWORD i = 0; i < nTables; i ++) { - const uint8_t* p = (const uint8_t*)pFont->m_FontTables + i * 16; - if (GET_TT_LONG(p) == table) { - offset = GET_TT_LONG(p + 8); - datasize = GET_TT_LONG(p + 12); - } - } - } - if (datasize && size >= datasize && pFile) { - FXSYS_fseek(pFile, offset, FXSYS_SEEK_SET); - FXSYS_fread(buffer, datasize, 1, pFile); - } - if (pFile) { - FXSYS_fclose(pFile); - } - return datasize; +void* CFX_FolderFontInfo::MapFont(int weight, + FX_BOOL bItalic, + int charset, + int pitch_family, + const FX_CHAR* family, + int& iExact) { + return NULL; } -void CFX_FolderFontInfo::DeleteFont(void* hFont) -{ +void* CFX_FolderFontInfo::GetFont(const FX_CHAR* face) { + void* p; + if (!m_FontList.Lookup(face, p)) { + return NULL; + } + return p; } -FX_BOOL CFX_FolderFontInfo::GetFaceName(void* hFont, CFX_ByteString& name) -{ - if (hFont == NULL) { - return FALSE; - } - CFontFaceInfo* pFont = (CFontFaceInfo*)hFont; - name = pFont->m_FaceName; - return TRUE; +FX_DWORD CFX_FolderFontInfo::GetFontData(void* hFont, + FX_DWORD table, + uint8_t* buffer, + FX_DWORD size) { + if (hFont == NULL) { + return 0; + } + CFontFaceInfo* pFont = (CFontFaceInfo*)hFont; + FXSYS_FILE* pFile = NULL; + if (size > 0) { + pFile = FXSYS_fopen(pFont->m_FilePath, "rb"); + if (pFile == NULL) { + return 0; + } + } + FX_DWORD datasize = 0; + FX_DWORD offset; + if (table == 0) { + datasize = pFont->m_FontOffset ? 0 : pFont->m_FileSize; + offset = 0; + } else if (table == 0x74746366) { + datasize = pFont->m_FontOffset ? pFont->m_FileSize : 0; + offset = 0; + } else { + FX_DWORD nTables = pFont->m_FontTables.GetLength() / 16; + for (FX_DWORD i = 0; i < nTables; i++) { + const uint8_t* p = (const uint8_t*)pFont->m_FontTables + i * 16; + if (GET_TT_LONG(p) == table) { + offset = GET_TT_LONG(p + 8); + datasize = GET_TT_LONG(p + 12); + } + } + } + if (datasize && size >= datasize && pFile) { + FXSYS_fseek(pFile, offset, FXSYS_SEEK_SET); + FXSYS_fread(buffer, datasize, 1, pFile); + } + if (pFile) { + FXSYS_fclose(pFile); + } + return datasize; } -FX_BOOL CFX_FolderFontInfo::GetFontCharset(void* hFont, int& charset) -{ +void CFX_FolderFontInfo::DeleteFont(void* hFont) {} +FX_BOOL CFX_FolderFontInfo::GetFaceName(void* hFont, CFX_ByteString& name) { + if (hFont == NULL) { return FALSE; + } + CFontFaceInfo* pFont = (CFontFaceInfo*)hFont; + name = pFont->m_FaceName; + return TRUE; +} +FX_BOOL CFX_FolderFontInfo::GetFontCharset(void* hFont, int& charset) { + return FALSE; } diff --git a/core/src/fxge/ge/fx_ge_linux.cpp b/core/src/fxge/ge/fx_ge_linux.cpp index 861afd259c..61202597f5 100644 --- a/core/src/fxge/ge/fx_ge_linux.cpp +++ b/core/src/fxge/ge/fx_ge_linux.cpp @@ -10,10 +10,9 @@ #if _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ static const struct { - const FX_CHAR* m_pName; - const FX_CHAR* m_pSubstName; -} -Base14Substs[] = { + const FX_CHAR* m_pName; + const FX_CHAR* m_pSubstName; +} Base14Substs[] = { {"Courier", "Courier New"}, {"Courier-Bold", "Courier New Bold"}, {"Courier-BoldOblique", "Courier New Bold Italic"}, @@ -27,205 +26,222 @@ Base14Substs[] = { {"Times-BoldItalic", "Times New Roman Bold Italic"}, {"Times-Italic", "Times New Roman Italic"}, }; -class CFX_LinuxFontInfo : public CFX_FolderFontInfo -{ -public: - void* MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, const FX_CHAR* family, int& iExact) override; - FX_BOOL ParseFontCfg(); - void* FindFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, const FX_CHAR* family, FX_BOOL bMatchName); +class CFX_LinuxFontInfo : public CFX_FolderFontInfo { + public: + void* MapFont(int weight, + FX_BOOL bItalic, + int charset, + int pitch_family, + const FX_CHAR* family, + int& iExact) override; + FX_BOOL ParseFontCfg(); + void* FindFont(int weight, + FX_BOOL bItalic, + int charset, + int pitch_family, + const FX_CHAR* family, + FX_BOOL bMatchName); }; -#define LINUX_GPNAMESIZE 6 +#define LINUX_GPNAMESIZE 6 static const struct { - const FX_CHAR* NameArr[LINUX_GPNAMESIZE]; -} -LinuxGpFontList[] = { - {{"TakaoPGothic", "VL PGothic", "IPAPGothic", "VL Gothic", "Kochi Gothic", "VL Gothic regular"}}, - {{"TakaoGothic", "VL Gothic", "IPAGothic", "Kochi Gothic", NULL, "VL Gothic regular"}}, - {{"TakaoPMincho", "IPAPMincho", "VL Gothic", "Kochi Mincho", NULL, "VL Gothic regular"}}, - {{"TakaoMincho", "IPAMincho", "VL Gothic", "Kochi Mincho", NULL, "VL Gothic regular"}}, + const FX_CHAR* NameArr[LINUX_GPNAMESIZE]; +} LinuxGpFontList[] = { + {{"TakaoPGothic", "VL PGothic", "IPAPGothic", "VL Gothic", "Kochi Gothic", + "VL Gothic regular"}}, + {{"TakaoGothic", "VL Gothic", "IPAGothic", "Kochi Gothic", NULL, + "VL Gothic regular"}}, + {{"TakaoPMincho", "IPAPMincho", "VL Gothic", "Kochi Mincho", NULL, + "VL Gothic regular"}}, + {{"TakaoMincho", "IPAMincho", "VL Gothic", "Kochi Mincho", NULL, + "VL Gothic regular"}}, }; static const FX_CHAR* const g_LinuxGbFontList[] = { - "AR PL UMing CN Light", - "WenQuanYi Micro Hei", - "AR PL UKai CN", + "AR PL UMing CN Light", "WenQuanYi Micro Hei", "AR PL UKai CN", }; static const FX_CHAR* const g_LinuxB5FontList[] = { - "AR PL UMing TW Light", - "WenQuanYi Micro Hei", - "AR PL UKai TW", + "AR PL UMing TW Light", "WenQuanYi Micro Hei", "AR PL UKai TW", }; static const FX_CHAR* const g_LinuxHGFontList[] = { "UnDotum", }; -static int32_t GetJapanesePreference(const FX_CHAR* facearr, int weight, int picth_family) -{ - CFX_ByteString face = facearr; - if (face.Find("Gothic") >= 0 || face.Find("\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) { - if (face.Find("PGothic") >= 0 || face.Find("\x82\x6f\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) { - return 0; - } - return 1; +static int32_t GetJapanesePreference(const FX_CHAR* facearr, + int weight, + int picth_family) { + CFX_ByteString face = facearr; + if (face.Find("Gothic") >= 0 || + face.Find("\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) { + if (face.Find("PGothic") >= 0 || + face.Find("\x82\x6f\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) { + return 0; } - if (face.Find("Mincho") >= 0 || face.Find("\x96\xbe\x92\xa9") >= 0) { - if (face.Find("PMincho") >= 0 || face.Find("\x82\x6f\x96\xbe\x92\xa9") >= 0) { - return 2; - } - return 3; - } - if (!(picth_family & FXFONT_FF_ROMAN) && weight > 400) { - return 0; - } - return 2; -} -void* CFX_LinuxFontInfo::MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, const FX_CHAR* cstr_face, int& iExact) -{ - CFX_ByteString face = cstr_face; - int iBaseFont; - for (iBaseFont = 0; iBaseFont < 12; iBaseFont ++) - if (face == CFX_ByteStringC(Base14Substs[iBaseFont].m_pName)) { - face = Base14Substs[iBaseFont].m_pSubstName; - iExact = 1; - break; - } - if (iBaseFont < 12) { - return GetFont(face); - } - void* p = NULL; - FX_BOOL bCJK = TRUE; - switch (charset) { - case FXFONT_SHIFTJIS_CHARSET: { - int32_t index = GetJapanesePreference(cstr_face, weight, pitch_family); - if (index < 0) { - break; - } - for (int32_t i = 0; i < LINUX_GPNAMESIZE; i++) - if (m_FontList.Lookup(LinuxGpFontList[index].NameArr[i], p)) { - return p; - } - } - break; - case FXFONT_GB2312_CHARSET: { - static int32_t s_gbCount = sizeof(g_LinuxGbFontList) / sizeof(const FX_CHAR*); - for (int32_t i = 0; i < s_gbCount; i++) - if (m_FontList.Lookup(g_LinuxGbFontList[i], p)) { - return p; - } - } - break; - case FXFONT_CHINESEBIG5_CHARSET: { - static int32_t s_b5Count = sizeof(g_LinuxB5FontList) / sizeof(const FX_CHAR*); - for (int32_t i = 0; i < s_b5Count; i++) - if (m_FontList.Lookup(g_LinuxB5FontList[i], p)) { - return p; - } - } - break; - case FXFONT_HANGEUL_CHARSET: { - static int32_t s_hgCount = sizeof(g_LinuxHGFontList) / sizeof(const FX_CHAR*); - for (int32_t i = 0; i < s_hgCount; i++) - if (m_FontList.Lookup(g_LinuxHGFontList[i], p)) { - return p; - } - } - break; - default: - bCJK = FALSE; - break; - } - if (charset == FXFONT_ANSI_CHARSET && (pitch_family & FXFONT_FF_FIXEDPITCH)) { - return GetFont("Courier New"); - } - return FindFont(weight, bItalic, charset, pitch_family, cstr_face, !bCJK); -} -static FX_DWORD _LinuxGetCharset(int charset) -{ - switch(charset) { - case FXFONT_SHIFTJIS_CHARSET: - return CHARSET_FLAG_SHIFTJIS; - case FXFONT_GB2312_CHARSET: - return CHARSET_FLAG_GB; - case FXFONT_CHINESEBIG5_CHARSET: - return CHARSET_FLAG_BIG5; - case FXFONT_HANGEUL_CHARSET: - return CHARSET_FLAG_KOREAN; - case FXFONT_SYMBOL_CHARSET: - return CHARSET_FLAG_SYMBOL; - case FXFONT_ANSI_CHARSET: - return CHARSET_FLAG_ANSI; - default: - break; + return 1; + } + if (face.Find("Mincho") >= 0 || face.Find("\x96\xbe\x92\xa9") >= 0) { + if (face.Find("PMincho") >= 0 || + face.Find("\x82\x6f\x96\xbe\x92\xa9") >= 0) { + return 2; } + return 3; + } + if (!(picth_family & FXFONT_FF_ROMAN) && weight > 400) { return 0; + } + return 2; } -static int32_t _LinuxGetSimilarValue(int weight, FX_BOOL bItalic, int pitch_family, FX_DWORD style) -{ - int32_t iSimilarValue = 0; - if ((style & FXFONT_BOLD) == (weight > 400)) { - iSimilarValue += 16; +void* CFX_LinuxFontInfo::MapFont(int weight, + FX_BOOL bItalic, + int charset, + int pitch_family, + const FX_CHAR* cstr_face, + int& iExact) { + CFX_ByteString face = cstr_face; + int iBaseFont; + for (iBaseFont = 0; iBaseFont < 12; iBaseFont++) + if (face == CFX_ByteStringC(Base14Substs[iBaseFont].m_pName)) { + face = Base14Substs[iBaseFont].m_pSubstName; + iExact = 1; + break; } - if ((style & FXFONT_ITALIC) == bItalic) { - iSimilarValue += 16; - } - if ((style & FXFONT_SERIF) == (pitch_family & FXFONT_FF_ROMAN)) { - iSimilarValue += 16; - } - if ((style & FXFONT_SCRIPT) == (pitch_family & FXFONT_FF_SCRIPT)) { - iSimilarValue += 8; - } - if ((style & FXFONT_FIXED_PITCH) == (pitch_family & FXFONT_FF_FIXEDPITCH)) { - iSimilarValue += 8; - } - return iSimilarValue; -} -void* CFX_LinuxFontInfo::FindFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, const FX_CHAR* family, FX_BOOL bMatchName) -{ - CFontFaceInfo* pFind = NULL; - FX_DWORD charset_flag = _LinuxGetCharset(charset); - int32_t iBestSimilar = 0; - FX_POSITION pos = m_FontList.GetStartPosition(); - while (pos) { - CFX_ByteString bsName; - CFontFaceInfo* pFont = NULL; - m_FontList.GetNextAssoc(pos, bsName, (void*&)pFont); - if (!(pFont->m_Charsets & charset_flag) && charset != FXFONT_DEFAULT_CHARSET) { - continue; + if (iBaseFont < 12) { + return GetFont(face); + } + void* p = NULL; + FX_BOOL bCJK = TRUE; + switch (charset) { + case FXFONT_SHIFTJIS_CHARSET: { + int32_t index = GetJapanesePreference(cstr_face, weight, pitch_family); + if (index < 0) { + break; + } + for (int32_t i = 0; i < LINUX_GPNAMESIZE; i++) + if (m_FontList.Lookup(LinuxGpFontList[index].NameArr[i], p)) { + return p; } - int32_t iSimilarValue = 0; - int32_t index = bsName.Find(family); - if (bMatchName && index < 0) { - continue; + } break; + case FXFONT_GB2312_CHARSET: { + static int32_t s_gbCount = + sizeof(g_LinuxGbFontList) / sizeof(const FX_CHAR*); + for (int32_t i = 0; i < s_gbCount; i++) + if (m_FontList.Lookup(g_LinuxGbFontList[i], p)) { + return p; } - if (!bMatchName && index > 0) { - iSimilarValue += 64; + } break; + case FXFONT_CHINESEBIG5_CHARSET: { + static int32_t s_b5Count = + sizeof(g_LinuxB5FontList) / sizeof(const FX_CHAR*); + for (int32_t i = 0; i < s_b5Count; i++) + if (m_FontList.Lookup(g_LinuxB5FontList[i], p)) { + return p; } - iSimilarValue = _LinuxGetSimilarValue(weight, bItalic, pitch_family, pFont->m_Styles); - if (iSimilarValue > iBestSimilar) { - iBestSimilar = iSimilarValue; - pFind = pFont; + } break; + case FXFONT_HANGEUL_CHARSET: { + static int32_t s_hgCount = + sizeof(g_LinuxHGFontList) / sizeof(const FX_CHAR*); + for (int32_t i = 0; i < s_hgCount; i++) + if (m_FontList.Lookup(g_LinuxHGFontList[i], p)) { + return p; } - } - return pFind; + } break; + default: + bCJK = FALSE; + break; + } + if (charset == FXFONT_ANSI_CHARSET && (pitch_family & FXFONT_FF_FIXEDPITCH)) { + return GetFont("Courier New"); + } + return FindFont(weight, bItalic, charset, pitch_family, cstr_face, !bCJK); } -IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault() -{ - CFX_LinuxFontInfo* pInfo = new CFX_LinuxFontInfo; - if (!pInfo->ParseFontCfg()) { - pInfo->AddPath("/usr/share/fonts"); - pInfo->AddPath("/usr/share/X11/fonts/Type1"); - pInfo->AddPath("/usr/share/X11/fonts/TTF"); - pInfo->AddPath("/usr/local/share/fonts"); +static FX_DWORD _LinuxGetCharset(int charset) { + switch (charset) { + case FXFONT_SHIFTJIS_CHARSET: + return CHARSET_FLAG_SHIFTJIS; + case FXFONT_GB2312_CHARSET: + return CHARSET_FLAG_GB; + case FXFONT_CHINESEBIG5_CHARSET: + return CHARSET_FLAG_BIG5; + case FXFONT_HANGEUL_CHARSET: + return CHARSET_FLAG_KOREAN; + case FXFONT_SYMBOL_CHARSET: + return CHARSET_FLAG_SYMBOL; + case FXFONT_ANSI_CHARSET: + return CHARSET_FLAG_ANSI; + default: + break; + } + return 0; +} +static int32_t _LinuxGetSimilarValue(int weight, + FX_BOOL bItalic, + int pitch_family, + FX_DWORD style) { + int32_t iSimilarValue = 0; + if ((style & FXFONT_BOLD) == (weight > 400)) { + iSimilarValue += 16; + } + if ((style & FXFONT_ITALIC) == bItalic) { + iSimilarValue += 16; + } + if ((style & FXFONT_SERIF) == (pitch_family & FXFONT_FF_ROMAN)) { + iSimilarValue += 16; + } + if ((style & FXFONT_SCRIPT) == (pitch_family & FXFONT_FF_SCRIPT)) { + iSimilarValue += 8; + } + if ((style & FXFONT_FIXED_PITCH) == (pitch_family & FXFONT_FF_FIXEDPITCH)) { + iSimilarValue += 8; + } + return iSimilarValue; +} +void* CFX_LinuxFontInfo::FindFont(int weight, + FX_BOOL bItalic, + int charset, + int pitch_family, + const FX_CHAR* family, + FX_BOOL bMatchName) { + CFontFaceInfo* pFind = NULL; + FX_DWORD charset_flag = _LinuxGetCharset(charset); + int32_t iBestSimilar = 0; + FX_POSITION pos = m_FontList.GetStartPosition(); + while (pos) { + CFX_ByteString bsName; + CFontFaceInfo* pFont = NULL; + m_FontList.GetNextAssoc(pos, bsName, (void*&)pFont); + if (!(pFont->m_Charsets & charset_flag) && + charset != FXFONT_DEFAULT_CHARSET) { + continue; + } + int32_t iSimilarValue = 0; + int32_t index = bsName.Find(family); + if (bMatchName && index < 0) { + continue; + } + if (!bMatchName && index > 0) { + iSimilarValue += 64; + } + iSimilarValue = + _LinuxGetSimilarValue(weight, bItalic, pitch_family, pFont->m_Styles); + if (iSimilarValue > iBestSimilar) { + iBestSimilar = iSimilarValue; + pFind = pFont; } - return pInfo; + } + return pFind; } -FX_BOOL CFX_LinuxFontInfo::ParseFontCfg() -{ - return FALSE; +IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault() { + CFX_LinuxFontInfo* pInfo = new CFX_LinuxFontInfo; + if (!pInfo->ParseFontCfg()) { + pInfo->AddPath("/usr/share/fonts"); + pInfo->AddPath("/usr/share/X11/fonts/Type1"); + pInfo->AddPath("/usr/share/X11/fonts/TTF"); + pInfo->AddPath("/usr/local/share/fonts"); + } + return pInfo; } -void CFX_GEModule::InitPlatform() -{ - m_pFontMgr->SetSystemFontInfo(IFX_SystemFontInfo::CreateDefault()); +FX_BOOL CFX_LinuxFontInfo::ParseFontCfg() { + return FALSE; } -void CFX_GEModule::DestroyPlatform() -{ +void CFX_GEModule::InitPlatform() { + m_pFontMgr->SetSystemFontInfo(IFX_SystemFontInfo::CreateDefault()); } +void CFX_GEModule::DestroyPlatform() {} #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ diff --git a/core/src/fxge/ge/fx_ge_path.cpp b/core/src/fxge/ge/fx_ge_path.cpp index b1410b3911..b50c271c20 100644 --- a/core/src/fxge/ge/fx_ge_path.cpp +++ b/core/src/fxge/ge/fx_ge_path.cpp @@ -8,624 +8,664 @@ #include "../../../include/fxcrt/fx_system.h" #include "../../../include/fxge/fx_ge.h" -CFX_ClipRgn::CFX_ClipRgn(int width, int height) -{ +CFX_ClipRgn::CFX_ClipRgn(int width, int height) { + m_Type = RectI; + m_Box.left = m_Box.top = 0; + m_Box.right = width; + m_Box.bottom = height; +} +CFX_ClipRgn::CFX_ClipRgn(const FX_RECT& rect) { + m_Type = RectI; + m_Box = rect; +} +CFX_ClipRgn::CFX_ClipRgn(const CFX_ClipRgn& src) { + m_Type = src.m_Type; + m_Box = src.m_Box; + m_Mask = src.m_Mask; +} +CFX_ClipRgn::~CFX_ClipRgn() {} +void CFX_ClipRgn::Reset(const FX_RECT& rect) { + m_Type = RectI; + m_Box = rect; + m_Mask.SetNull(); +} +void CFX_ClipRgn::IntersectRect(const FX_RECT& rect) { + if (m_Type == RectI) { + m_Box.Intersect(rect); + return; + } + if (m_Type == MaskF) { + IntersectMaskRect(rect, m_Box, m_Mask); + return; + } +} +void CFX_ClipRgn::IntersectMaskRect(FX_RECT rect, + FX_RECT mask_rect, + CFX_DIBitmapRef Mask) { + const CFX_DIBitmap* mask_dib = Mask; + m_Type = MaskF; + m_Box = rect; + m_Box.Intersect(mask_rect); + if (m_Box.IsEmpty()) { m_Type = RectI; - m_Box.left = m_Box.top = 0; - m_Box.right = width; - m_Box.bottom = height; -} -CFX_ClipRgn::CFX_ClipRgn(const FX_RECT& rect) -{ - m_Type = RectI; - m_Box = rect; -} -CFX_ClipRgn::CFX_ClipRgn(const CFX_ClipRgn& src) -{ - m_Type = src.m_Type; - m_Box = src.m_Box; - m_Mask = src.m_Mask; -} -CFX_ClipRgn::~CFX_ClipRgn() -{ -} -void CFX_ClipRgn::Reset(const FX_RECT& rect) -{ - m_Type = RectI; - m_Box = rect; - m_Mask.SetNull(); -} -void CFX_ClipRgn::IntersectRect(const FX_RECT& rect) -{ - if (m_Type == RectI) { - m_Box.Intersect(rect); - return; - } - if (m_Type == MaskF) { - IntersectMaskRect(rect, m_Box, m_Mask); - return; - } -} -void CFX_ClipRgn::IntersectMaskRect(FX_RECT rect, FX_RECT mask_rect, CFX_DIBitmapRef Mask) -{ - const CFX_DIBitmap* mask_dib = Mask; - m_Type = MaskF; - m_Box = rect; - m_Box.Intersect(mask_rect); - if (m_Box.IsEmpty()) { - m_Type = RectI; - return; - } - if (m_Box == mask_rect) { - m_Mask = Mask; - return; - } - CFX_DIBitmap* new_dib = m_Mask.New(); + return; + } + if (m_Box == mask_rect) { + m_Mask = Mask; + return; + } + CFX_DIBitmap* new_dib = m_Mask.New(); + if (!new_dib) { + return; + } + new_dib->Create(m_Box.Width(), m_Box.Height(), FXDIB_8bppMask); + for (int row = m_Box.top; row < m_Box.bottom; row++) { + uint8_t* dest_scan = + new_dib->GetBuffer() + new_dib->GetPitch() * (row - m_Box.top); + uint8_t* src_scan = + mask_dib->GetBuffer() + mask_dib->GetPitch() * (row - mask_rect.top); + for (int col = m_Box.left; col < m_Box.right; col++) { + dest_scan[col - m_Box.left] = src_scan[col - mask_rect.left]; + } + } +} +void CFX_ClipRgn::IntersectMaskF(int left, int top, CFX_DIBitmapRef Mask) { + const CFX_DIBitmap* mask_dib = Mask; + ASSERT(mask_dib->GetFormat() == FXDIB_8bppMask); + FX_RECT mask_box(left, top, left + mask_dib->GetWidth(), + top + mask_dib->GetHeight()); + if (m_Type == RectI) { + IntersectMaskRect(m_Box, mask_box, Mask); + return; + } + if (m_Type == MaskF) { + FX_RECT new_box = m_Box; + new_box.Intersect(mask_box); + if (new_box.IsEmpty()) { + m_Type = RectI; + m_Mask.SetNull(); + m_Box = new_box; + return; + } + CFX_DIBitmapRef new_mask; + CFX_DIBitmap* new_dib = new_mask.New(); if (!new_dib) { - return; - } - new_dib->Create(m_Box.Width(), m_Box.Height(), FXDIB_8bppMask); - for (int row = m_Box.top; row < m_Box.bottom; row ++) { - uint8_t* dest_scan = new_dib->GetBuffer() + new_dib->GetPitch() * (row - m_Box.top); - uint8_t* src_scan = mask_dib->GetBuffer() + mask_dib->GetPitch() * (row - mask_rect.top); - for (int col = m_Box.left; col < m_Box.right; col ++) { - dest_scan[col - m_Box.left] = src_scan[col - mask_rect.left]; - } - } -} -void CFX_ClipRgn::IntersectMaskF(int left, int top, CFX_DIBitmapRef Mask) -{ - const CFX_DIBitmap* mask_dib = Mask; - ASSERT(mask_dib->GetFormat() == FXDIB_8bppMask); - FX_RECT mask_box(left, top, left + mask_dib->GetWidth(), top + mask_dib->GetHeight()); - if (m_Type == RectI) { - IntersectMaskRect(m_Box, mask_box, Mask); - return; - } - if (m_Type == MaskF) { - FX_RECT new_box = m_Box; - new_box.Intersect(mask_box); - if (new_box.IsEmpty()) { - m_Type = RectI; - m_Mask.SetNull(); - m_Box = new_box; - return; - } - CFX_DIBitmapRef new_mask; - CFX_DIBitmap* new_dib = new_mask.New(); - if (!new_dib) { - return; - } - new_dib->Create(new_box.Width(), new_box.Height(), FXDIB_8bppMask); - const CFX_DIBitmap* old_dib = m_Mask; - for (int row = new_box.top; row < new_box.bottom; row ++) { - uint8_t* old_scan = old_dib->GetBuffer() + (row - m_Box.top) * old_dib->GetPitch(); - uint8_t* mask_scan = mask_dib->GetBuffer() + (row - top) * mask_dib->GetPitch(); - uint8_t* new_scan = new_dib->GetBuffer() + (row - new_box.top) * new_dib->GetPitch(); - for (int col = new_box.left; col < new_box.right; col ++) { - new_scan[col - new_box.left] = old_scan[col - m_Box.left] * mask_scan[col - left] / 255; - } - } - m_Box = new_box; - m_Mask = new_mask; - return; - } - ASSERT(FALSE); -} -CFX_PathData::CFX_PathData() -{ - m_PointCount = m_AllocCount = 0; - m_pPoints = NULL; -} -CFX_PathData::~CFX_PathData() -{ + return; + } + new_dib->Create(new_box.Width(), new_box.Height(), FXDIB_8bppMask); + const CFX_DIBitmap* old_dib = m_Mask; + for (int row = new_box.top; row < new_box.bottom; row++) { + uint8_t* old_scan = + old_dib->GetBuffer() + (row - m_Box.top) * old_dib->GetPitch(); + uint8_t* mask_scan = + mask_dib->GetBuffer() + (row - top) * mask_dib->GetPitch(); + uint8_t* new_scan = + new_dib->GetBuffer() + (row - new_box.top) * new_dib->GetPitch(); + for (int col = new_box.left; col < new_box.right; col++) { + new_scan[col - new_box.left] = + old_scan[col - m_Box.left] * mask_scan[col - left] / 255; + } + } + m_Box = new_box; + m_Mask = new_mask; + return; + } + ASSERT(FALSE); +} +CFX_PathData::CFX_PathData() { + m_PointCount = m_AllocCount = 0; + m_pPoints = NULL; +} +CFX_PathData::~CFX_PathData() { + if (m_pPoints) { + FX_Free(m_pPoints); + } +} +void CFX_PathData::SetPointCount(int nPoints) { + m_PointCount = nPoints; + if (m_AllocCount < nPoints) { if (m_pPoints) { - FX_Free(m_pPoints); - } -} -void CFX_PathData::SetPointCount(int nPoints) -{ - m_PointCount = nPoints; - if (m_AllocCount < nPoints) { - if (m_pPoints) { - FX_Free(m_pPoints); - m_pPoints = NULL; - } - m_pPoints = FX_Alloc(FX_PATHPOINT, nPoints); - m_AllocCount = nPoints; - } -} -void CFX_PathData::AllocPointCount(int nPoints) -{ - if (m_AllocCount < nPoints) { - FX_PATHPOINT* pNewBuf = FX_Alloc(FX_PATHPOINT, nPoints); - if (m_PointCount) { - FXSYS_memcpy(pNewBuf, m_pPoints, m_PointCount * sizeof(FX_PATHPOINT)); - } - if (m_pPoints) { - FX_Free(m_pPoints); - } - m_pPoints = pNewBuf; - m_AllocCount = nPoints; + FX_Free(m_pPoints); + m_pPoints = NULL; } + m_pPoints = FX_Alloc(FX_PATHPOINT, nPoints); + m_AllocCount = nPoints; + } } -CFX_PathData::CFX_PathData(const CFX_PathData& src) -{ - m_PointCount = m_AllocCount = src.m_PointCount; - m_pPoints = FX_Alloc(FX_PATHPOINT, src.m_PointCount); - FXSYS_memcpy(m_pPoints, src.m_pPoints, sizeof(FX_PATHPOINT) * m_PointCount); -} -void CFX_PathData::TrimPoints(int nPoints) -{ - if (m_PointCount <= nPoints) { - return; - } - SetPointCount(nPoints); -} -void CFX_PathData::AddPointCount(int addPoints) -{ - pdfium::base::CheckedNumeric safe_new_count = m_PointCount; - safe_new_count += addPoints; - int new_count = safe_new_count.ValueOrDie(); - AllocPointCount(new_count); - m_PointCount = new_count; -} -void CFX_PathData::Append(const CFX_PathData* pSrc, const CFX_AffineMatrix* pMatrix) -{ - int old_count = m_PointCount; - AddPointCount(pSrc->m_PointCount); - FXSYS_memcpy(m_pPoints + old_count, pSrc->m_pPoints, pSrc->m_PointCount * sizeof(FX_PATHPOINT)); - if (pMatrix) { - for (int i = 0; i < pSrc->m_PointCount; i ++) { - pMatrix->Transform(m_pPoints[old_count + i].m_PointX, m_pPoints[old_count + i].m_PointY); - } - } -} -void CFX_PathData::SetPoint(int index, FX_FLOAT x, FX_FLOAT y, int flag) -{ - ASSERT(index < m_PointCount); - m_pPoints[index].m_PointX = x; - m_pPoints[index].m_PointY = y; - m_pPoints[index].m_Flag = flag; -} -void CFX_PathData::AppendRect(FX_FLOAT left, FX_FLOAT bottom, FX_FLOAT right, FX_FLOAT top) -{ - int old_count = m_PointCount; - AddPointCount(5); - FX_PATHPOINT* pPoints = m_pPoints + old_count; - pPoints[0].m_PointX = pPoints[1].m_PointX = pPoints[4].m_PointX = left; - pPoints[2].m_PointX = pPoints[3].m_PointX = right; - pPoints[0].m_PointY = pPoints[3].m_PointY = pPoints[4].m_PointY = bottom; - pPoints[1].m_PointY = pPoints[2].m_PointY = top; - pPoints[0].m_Flag = FXPT_MOVETO; - pPoints[1].m_Flag = pPoints[2].m_Flag = pPoints[3].m_Flag = FXPT_LINETO; - pPoints[4].m_Flag = FXPT_LINETO | FXPT_CLOSEFIGURE; -} -CFX_FloatRect CFX_PathData::GetBoundingBox() const -{ - CFX_FloatRect rect; +void CFX_PathData::AllocPointCount(int nPoints) { + if (m_AllocCount < nPoints) { + FX_PATHPOINT* pNewBuf = FX_Alloc(FX_PATHPOINT, nPoints); if (m_PointCount) { - rect.InitRect(m_pPoints[0].m_PointX, m_pPoints[0].m_PointY); - for (int i = 1; i < m_PointCount; i ++) { - rect.UpdateRect(m_pPoints[i].m_PointX, m_pPoints[i].m_PointY); - } - } - return rect; -} -static void _UpdateLineEndPoints(CFX_FloatRect& rect, FX_FLOAT start_x, FX_FLOAT start_y, FX_FLOAT end_x, FX_FLOAT end_y, - FX_FLOAT hw) -{ - if (start_x == end_x) { - if (start_y == end_y) { - rect.UpdateRect(end_x + hw, end_y + hw); - rect.UpdateRect(end_x - hw, end_y - hw); - return; - } - FX_FLOAT point_y; - if (end_y < start_y) { - point_y = end_y - hw; - } else { - point_y = end_y + hw; - } - rect.UpdateRect(end_x + hw, point_y); - rect.UpdateRect(end_x - hw, point_y); - return; + FXSYS_memcpy(pNewBuf, m_pPoints, m_PointCount * sizeof(FX_PATHPOINT)); } + if (m_pPoints) { + FX_Free(m_pPoints); + } + m_pPoints = pNewBuf; + m_AllocCount = nPoints; + } +} +CFX_PathData::CFX_PathData(const CFX_PathData& src) { + m_PointCount = m_AllocCount = src.m_PointCount; + m_pPoints = FX_Alloc(FX_PATHPOINT, src.m_PointCount); + FXSYS_memcpy(m_pPoints, src.m_pPoints, sizeof(FX_PATHPOINT) * m_PointCount); +} +void CFX_PathData::TrimPoints(int nPoints) { + if (m_PointCount <= nPoints) { + return; + } + SetPointCount(nPoints); +} +void CFX_PathData::AddPointCount(int addPoints) { + pdfium::base::CheckedNumeric safe_new_count = m_PointCount; + safe_new_count += addPoints; + int new_count = safe_new_count.ValueOrDie(); + AllocPointCount(new_count); + m_PointCount = new_count; +} +void CFX_PathData::Append(const CFX_PathData* pSrc, + const CFX_AffineMatrix* pMatrix) { + int old_count = m_PointCount; + AddPointCount(pSrc->m_PointCount); + FXSYS_memcpy(m_pPoints + old_count, pSrc->m_pPoints, + pSrc->m_PointCount * sizeof(FX_PATHPOINT)); + if (pMatrix) { + for (int i = 0; i < pSrc->m_PointCount; i++) { + pMatrix->Transform(m_pPoints[old_count + i].m_PointX, + m_pPoints[old_count + i].m_PointY); + } + } +} +void CFX_PathData::SetPoint(int index, FX_FLOAT x, FX_FLOAT y, int flag) { + ASSERT(index < m_PointCount); + m_pPoints[index].m_PointX = x; + m_pPoints[index].m_PointY = y; + m_pPoints[index].m_Flag = flag; +} +void CFX_PathData::AppendRect(FX_FLOAT left, + FX_FLOAT bottom, + FX_FLOAT right, + FX_FLOAT top) { + int old_count = m_PointCount; + AddPointCount(5); + FX_PATHPOINT* pPoints = m_pPoints + old_count; + pPoints[0].m_PointX = pPoints[1].m_PointX = pPoints[4].m_PointX = left; + pPoints[2].m_PointX = pPoints[3].m_PointX = right; + pPoints[0].m_PointY = pPoints[3].m_PointY = pPoints[4].m_PointY = bottom; + pPoints[1].m_PointY = pPoints[2].m_PointY = top; + pPoints[0].m_Flag = FXPT_MOVETO; + pPoints[1].m_Flag = pPoints[2].m_Flag = pPoints[3].m_Flag = FXPT_LINETO; + pPoints[4].m_Flag = FXPT_LINETO | FXPT_CLOSEFIGURE; +} +CFX_FloatRect CFX_PathData::GetBoundingBox() const { + CFX_FloatRect rect; + if (m_PointCount) { + rect.InitRect(m_pPoints[0].m_PointX, m_pPoints[0].m_PointY); + for (int i = 1; i < m_PointCount; i++) { + rect.UpdateRect(m_pPoints[i].m_PointX, m_pPoints[i].m_PointY); + } + } + return rect; +} +static void _UpdateLineEndPoints(CFX_FloatRect& rect, + FX_FLOAT start_x, + FX_FLOAT start_y, + FX_FLOAT end_x, + FX_FLOAT end_y, + FX_FLOAT hw) { + if (start_x == end_x) { if (start_y == end_y) { - FX_FLOAT point_x; - if (end_x < start_x) { - point_x = end_x - hw; - } else { - point_x = end_x + hw; - } - rect.UpdateRect(point_x, end_y + hw); - rect.UpdateRect(point_x, end_y - hw); - return; - } - FX_FLOAT dx = end_x - start_x; - FX_FLOAT dy = end_y - start_y; - FX_FLOAT ll = FXSYS_sqrt2(dx, dy); - FX_FLOAT mx = end_x + hw * dx / ll; - FX_FLOAT my = end_y + hw * dy / ll; - FX_FLOAT dx1 = hw * dy / ll; - FX_FLOAT dy1 = hw * dx / ll; - rect.UpdateRect(mx - dx1, my + dy1); - rect.UpdateRect(mx + dx1, my - dy1); -} -static void _UpdateLineJoinPoints(CFX_FloatRect& rect, FX_FLOAT start_x, FX_FLOAT start_y, - FX_FLOAT middle_x, FX_FLOAT middle_y, FX_FLOAT end_x, FX_FLOAT end_y, - FX_FLOAT half_width, FX_FLOAT miter_limit) -{ - FX_FLOAT start_k = 0, start_c = 0, end_k = 0, end_c = 0, start_len = 0, start_dc = 0, end_len = 0, end_dc = 0; - FX_BOOL bStartVert = FXSYS_fabs(start_x - middle_x) < 1.0f / 20; - FX_BOOL bEndVert = FXSYS_fabs(middle_x - end_x) < 1.0f / 20; - if (bStartVert && bEndVert) { - int start_dir = middle_y > start_y ? 1 : -1; - FX_FLOAT point_y = middle_y + half_width * start_dir; - rect.UpdateRect(middle_x + half_width, point_y); - rect.UpdateRect(middle_x - half_width, point_y); - return; - } - if (!bStartVert) { - start_k = FXSYS_Div(middle_y - start_y, middle_x - start_x); - start_c = middle_y - FXSYS_Mul(start_k, middle_x); - start_len = FXSYS_sqrt2(start_x - middle_x, start_y - middle_y); - start_dc = (FX_FLOAT)FXSYS_fabs(FXSYS_MulDiv(half_width, start_len, start_x - middle_x)); - } - if (!bEndVert) { - end_k = FXSYS_Div(end_y - middle_y, end_x - middle_x); - end_c = middle_y - FXSYS_Mul(end_k, middle_x); - end_len = FXSYS_sqrt2(end_x - middle_x, end_y - middle_y); - end_dc = (FX_FLOAT)FXSYS_fabs(FXSYS_MulDiv(half_width, end_len, end_x - middle_x)); - } - if (bStartVert) { - FX_FLOAT outside_x = start_x; - if (end_x < start_x) { - outside_x += half_width; - } else { - outside_x -= half_width; - } - FX_FLOAT outside_y; - if (start_y < FXSYS_Mul(end_k, start_x) + end_c) { - outside_y = FXSYS_Mul(end_k, outside_x) + end_c + end_dc; - } else { - outside_y = FXSYS_Mul(end_k, outside_x) + end_c - end_dc; - } - rect.UpdateRect(outside_x, outside_y); - return; + rect.UpdateRect(end_x + hw, end_y + hw); + rect.UpdateRect(end_x - hw, end_y - hw); + return; } - if (bEndVert) { - FX_FLOAT outside_x = end_x; - if (start_x < end_x) { - outside_x += half_width; - } else { - outside_x -= half_width; - } - FX_FLOAT outside_y; - if (end_y < FXSYS_Mul(start_k, end_x) + start_c) { - outside_y = FXSYS_Mul(start_k, outside_x) + start_c + start_dc; - } else { - outside_y = FXSYS_Mul(start_k, outside_x) + start_c - start_dc; - } - rect.UpdateRect(outside_x, outside_y); - return; - } - if (FXSYS_fabs(start_k - end_k) < 1.0f / 20) { - int start_dir = middle_x > start_x ? 1 : -1; - int end_dir = end_x > middle_x ? 1 : -1; - if (start_dir == end_dir) { - _UpdateLineEndPoints(rect, middle_x, middle_y, end_x, end_y, half_width); - } else { - _UpdateLineEndPoints(rect, start_x, start_y, middle_x, middle_y, half_width); - } - return; - } - FX_FLOAT start_outside_c = start_c; - if (end_y < FXSYS_Mul(start_k, end_x) + start_c) { - start_outside_c += start_dc; + FX_FLOAT point_y; + if (end_y < start_y) { + point_y = end_y - hw; + } else { + point_y = end_y + hw; + } + rect.UpdateRect(end_x + hw, point_y); + rect.UpdateRect(end_x - hw, point_y); + return; + } + if (start_y == end_y) { + FX_FLOAT point_x; + if (end_x < start_x) { + point_x = end_x - hw; } else { - start_outside_c -= start_dc; + point_x = end_x + hw; + } + rect.UpdateRect(point_x, end_y + hw); + rect.UpdateRect(point_x, end_y - hw); + return; + } + FX_FLOAT dx = end_x - start_x; + FX_FLOAT dy = end_y - start_y; + FX_FLOAT ll = FXSYS_sqrt2(dx, dy); + FX_FLOAT mx = end_x + hw * dx / ll; + FX_FLOAT my = end_y + hw * dy / ll; + FX_FLOAT dx1 = hw * dy / ll; + FX_FLOAT dy1 = hw * dx / ll; + rect.UpdateRect(mx - dx1, my + dy1); + rect.UpdateRect(mx + dx1, my - dy1); +} +static void _UpdateLineJoinPoints(CFX_FloatRect& rect, + FX_FLOAT start_x, + FX_FLOAT start_y, + FX_FLOAT middle_x, + FX_FLOAT middle_y, + FX_FLOAT end_x, + FX_FLOAT end_y, + FX_FLOAT half_width, + FX_FLOAT miter_limit) { + FX_FLOAT start_k = 0, start_c = 0, end_k = 0, end_c = 0, start_len = 0, + start_dc = 0, end_len = 0, end_dc = 0; + FX_BOOL bStartVert = FXSYS_fabs(start_x - middle_x) < 1.0f / 20; + FX_BOOL bEndVert = FXSYS_fabs(middle_x - end_x) < 1.0f / 20; + if (bStartVert && bEndVert) { + int start_dir = middle_y > start_y ? 1 : -1; + FX_FLOAT point_y = middle_y + half_width * start_dir; + rect.UpdateRect(middle_x + half_width, point_y); + rect.UpdateRect(middle_x - half_width, point_y); + return; + } + if (!bStartVert) { + start_k = FXSYS_Div(middle_y - start_y, middle_x - start_x); + start_c = middle_y - FXSYS_Mul(start_k, middle_x); + start_len = FXSYS_sqrt2(start_x - middle_x, start_y - middle_y); + start_dc = (FX_FLOAT)FXSYS_fabs( + FXSYS_MulDiv(half_width, start_len, start_x - middle_x)); + } + if (!bEndVert) { + end_k = FXSYS_Div(end_y - middle_y, end_x - middle_x); + end_c = middle_y - FXSYS_Mul(end_k, middle_x); + end_len = FXSYS_sqrt2(end_x - middle_x, end_y - middle_y); + end_dc = (FX_FLOAT)FXSYS_fabs( + FXSYS_MulDiv(half_width, end_len, end_x - middle_x)); + } + if (bStartVert) { + FX_FLOAT outside_x = start_x; + if (end_x < start_x) { + outside_x += half_width; + } else { + outside_x -= half_width; } - FX_FLOAT end_outside_c = end_c; + FX_FLOAT outside_y; if (start_y < FXSYS_Mul(end_k, start_x) + end_c) { - end_outside_c += end_dc; + outside_y = FXSYS_Mul(end_k, outside_x) + end_c + end_dc; } else { - end_outside_c -= end_dc; - } - FX_FLOAT join_x = FXSYS_Div(end_outside_c - start_outside_c, start_k - end_k); - FX_FLOAT join_y = FXSYS_Mul(start_k, join_x) + start_outside_c; - rect.UpdateRect(join_x, join_y); -} -CFX_FloatRect CFX_PathData::GetBoundingBox(FX_FLOAT line_width, FX_FLOAT miter_limit) const -{ - CFX_FloatRect rect(100000 * 1.0f, 100000 * 1.0f, -100000 * 1.0f, -100000 * 1.0f); - int iPoint = 0; - FX_FLOAT half_width = line_width; - int iStartPoint, iEndPoint, iMiddlePoint; - FX_BOOL bJoin; - while (iPoint < m_PointCount) { - if (m_pPoints[iPoint].m_Flag == FXPT_MOVETO) { - iStartPoint = iPoint + 1; - iEndPoint = iPoint; - bJoin = FALSE; - } else { - if (m_pPoints[iPoint].m_Flag == FXPT_BEZIERTO) { - rect.UpdateRect(m_pPoints[iPoint].m_PointX, m_pPoints[iPoint].m_PointY); - rect.UpdateRect(m_pPoints[iPoint + 1].m_PointX, m_pPoints[iPoint + 1].m_PointY); - iPoint += 2; - } - if (iPoint == m_PointCount - 1 || m_pPoints[iPoint + 1].m_Flag == FXPT_MOVETO) { - iStartPoint = iPoint - 1; - iEndPoint = iPoint; - bJoin = FALSE; - } else { - iStartPoint = iPoint - 1; - iMiddlePoint = iPoint; - iEndPoint = iPoint + 1; - bJoin = TRUE; - } - } - FX_FLOAT start_x = m_pPoints[iStartPoint].m_PointX; - FX_FLOAT start_y = m_pPoints[iStartPoint].m_PointY; - FX_FLOAT end_x = m_pPoints[iEndPoint].m_PointX; - FX_FLOAT end_y = m_pPoints[iEndPoint].m_PointY; - if (bJoin) { - FX_FLOAT middle_x = m_pPoints[iMiddlePoint].m_PointX; - FX_FLOAT middle_y = m_pPoints[iMiddlePoint].m_PointY; - _UpdateLineJoinPoints(rect, start_x, start_y, middle_x, middle_y, end_x, end_y, half_width, miter_limit); - } else { - _UpdateLineEndPoints(rect, start_x, start_y, end_x, end_y, half_width); - } - iPoint ++; - } - return rect; -} -void CFX_PathData::Transform(const CFX_AffineMatrix* pMatrix) -{ - if (pMatrix == NULL) { - return; - } - for (int i = 0; i < m_PointCount; i ++) { - pMatrix->Transform(m_pPoints[i].m_PointX, m_pPoints[i].m_PointY); - } -} -FX_BOOL CFX_PathData::GetZeroAreaPath(CFX_PathData& NewPath, CFX_AffineMatrix* pMatrix, FX_BOOL&bThin, FX_BOOL bAdjust) const -{ - if (m_PointCount < 3) { - return FALSE; - } - if (m_PointCount == 3 && (m_pPoints[0].m_Flag & FXPT_TYPE) == FXPT_MOVETO && - (m_pPoints[1].m_Flag & FXPT_TYPE) == FXPT_LINETO && (m_pPoints[2].m_Flag & FXPT_TYPE) == FXPT_LINETO - && m_pPoints[0].m_PointX == m_pPoints[2].m_PointX && m_pPoints[0].m_PointY == m_pPoints[2].m_PointY) { - NewPath.AddPointCount(2); - if (bAdjust) { - if (pMatrix) { - FX_FLOAT x = m_pPoints[0].m_PointX, y = m_pPoints[0].m_PointY; - pMatrix->TransformPoint(x, y); - x = (int)x + 0.5f; - y = (int)y + 0.5f; - NewPath.SetPoint(0, x, y, FXPT_MOVETO); - x = m_pPoints[1].m_PointX, y = m_pPoints[1].m_PointY; - pMatrix->TransformPoint(x, y); - x = (int)x + 0.5f; - y = (int)y + 0.5f; - NewPath.SetPoint(1, x, y, FXPT_LINETO); - pMatrix->SetIdentity(); - } else { - FX_FLOAT x = (int)m_pPoints[0].m_PointX + 0.5f, y = (int)m_pPoints[0].m_PointY + 0.5f; - NewPath.SetPoint(0, x, y, FXPT_MOVETO); - x = (int)m_pPoints[1].m_PointX + 0.5f, y = (int)m_pPoints[1].m_PointY + 0.5f; - NewPath.SetPoint(1, x, y, FXPT_LINETO); - } - } else { - NewPath.SetPoint(0, m_pPoints[0].m_PointX, m_pPoints[0].m_PointY, FXPT_MOVETO); - NewPath.SetPoint(1, m_pPoints[1].m_PointX, m_pPoints[1].m_PointY, FXPT_LINETO); - } - if (m_pPoints[0].m_PointX != m_pPoints[1].m_PointX && m_pPoints[0].m_PointY != m_pPoints[1].m_PointY) { - bThin = TRUE; - } - return TRUE; - } - if (((m_PointCount > 3) && (m_PointCount % 2))) { - int mid = m_PointCount / 2; - FX_BOOL bZeroArea = FALSE; - CFX_PathData t_path; - for (int i = 0; i < mid; i++) { - if (!(m_pPoints[mid - i - 1].m_PointX == m_pPoints[mid + i + 1].m_PointX - && m_pPoints[mid - i - 1].m_PointY == m_pPoints[mid + i + 1].m_PointY && - ((m_pPoints[mid - i - 1].m_Flag & FXPT_TYPE) != FXPT_BEZIERTO && (m_pPoints[mid + i + 1].m_Flag & FXPT_TYPE) != FXPT_BEZIERTO))) { - bZeroArea = TRUE; - break; - } - int new_count = t_path.GetPointCount(); - t_path.AddPointCount(2); - t_path.SetPoint(new_count, m_pPoints[mid - i].m_PointX, m_pPoints[mid - i].m_PointY, FXPT_MOVETO); - t_path.SetPoint(new_count + 1, m_pPoints[mid - i - 1].m_PointX, m_pPoints[mid - i - 1].m_PointY, FXPT_LINETO); - } - if (!bZeroArea) { - NewPath.Append(&t_path, NULL); - bThin = TRUE; - return TRUE; - } - } - int stratPoint = 0; - int next = 0, i; - for (i = 0; i < m_PointCount; i++) { - int point_type = m_pPoints[i].m_Flag & FXPT_TYPE; - if (point_type == FXPT_MOVETO) { - stratPoint = i; - } else if (point_type == FXPT_LINETO) { - next = (i + 1 - stratPoint) % (m_PointCount - stratPoint) + stratPoint; - if ((m_pPoints[next].m_Flag & FXPT_TYPE) != FXPT_BEZIERTO && (m_pPoints[next].m_Flag & FXPT_TYPE) != FXPT_MOVETO) { - if((m_pPoints[i - 1].m_PointX == m_pPoints[i].m_PointX && m_pPoints[i].m_PointX == m_pPoints[next].m_PointX) - && ((m_pPoints[i].m_PointY - m_pPoints[i - 1].m_PointY) * (m_pPoints[i].m_PointY - m_pPoints[next].m_PointY) > 0)) { - int pre = i; - if (FXSYS_fabs(m_pPoints[i].m_PointY - m_pPoints[i - 1].m_PointY) - < FXSYS_fabs(m_pPoints[i].m_PointY - m_pPoints[next].m_PointY)) { - pre --; - next--; - } - int new_count = NewPath.GetPointCount(); - NewPath.AddPointCount(2); - NewPath.SetPoint(new_count, m_pPoints[pre].m_PointX, m_pPoints[pre].m_PointY, FXPT_MOVETO); - NewPath.SetPoint(new_count + 1, m_pPoints[next].m_PointX, m_pPoints[next].m_PointY, FXPT_LINETO); - } else if((m_pPoints[i - 1].m_PointY == m_pPoints[i].m_PointY && m_pPoints[i].m_PointY == m_pPoints[next].m_PointY) - && ((m_pPoints[i].m_PointX - m_pPoints[i - 1].m_PointX) * (m_pPoints[i].m_PointX - m_pPoints[next].m_PointX) > 0)) { - int pre = i; - if (FXSYS_fabs(m_pPoints[i].m_PointX - m_pPoints[i - 1].m_PointX) - < FXSYS_fabs(m_pPoints[i].m_PointX - m_pPoints[next].m_PointX)) { - pre --; - next--; - } - int new_count = NewPath.GetPointCount(); - NewPath.AddPointCount(2); - NewPath.SetPoint(new_count, m_pPoints[pre].m_PointX, m_pPoints[pre].m_PointY, FXPT_MOVETO); - NewPath.SetPoint(new_count + 1, m_pPoints[next].m_PointX, m_pPoints[next].m_PointY, FXPT_LINETO); - } else if ((m_pPoints[i - 1].m_Flag & FXPT_TYPE) == FXPT_MOVETO && (m_pPoints[next].m_Flag & FXPT_TYPE) == FXPT_LINETO && - m_pPoints[i - 1].m_PointX == m_pPoints[next].m_PointX && m_pPoints[i - 1].m_PointY == m_pPoints[next].m_PointY - && m_pPoints[next].m_Flag & FXPT_CLOSEFIGURE) { - int new_count = NewPath.GetPointCount(); - NewPath.AddPointCount(2); - NewPath.SetPoint(new_count, m_pPoints[i - 1].m_PointX, m_pPoints[i - 1].m_PointY, FXPT_MOVETO); - NewPath.SetPoint(new_count + 1, m_pPoints[i].m_PointX, m_pPoints[i].m_PointY, FXPT_LINETO); - bThin = TRUE; - } - } - } else if (point_type == FXPT_BEZIERTO) { - i += 2; - continue; - } + outside_y = FXSYS_Mul(end_k, outside_x) + end_c - end_dc; + } + rect.UpdateRect(outside_x, outside_y); + return; + } + if (bEndVert) { + FX_FLOAT outside_x = end_x; + if (start_x < end_x) { + outside_x += half_width; + } else { + outside_x -= half_width; } - if (m_PointCount > 3 && NewPath.GetPointCount()) { - bThin = TRUE; + FX_FLOAT outside_y; + if (end_y < FXSYS_Mul(start_k, end_x) + start_c) { + outside_y = FXSYS_Mul(start_k, outside_x) + start_c + start_dc; + } else { + outside_y = FXSYS_Mul(start_k, outside_x) + start_c - start_dc; + } + rect.UpdateRect(outside_x, outside_y); + return; + } + if (FXSYS_fabs(start_k - end_k) < 1.0f / 20) { + int start_dir = middle_x > start_x ? 1 : -1; + int end_dir = end_x > middle_x ? 1 : -1; + if (start_dir == end_dir) { + _UpdateLineEndPoints(rect, middle_x, middle_y, end_x, end_y, half_width); + } else { + _UpdateLineEndPoints(rect, start_x, start_y, middle_x, middle_y, + half_width); + } + return; + } + FX_FLOAT start_outside_c = start_c; + if (end_y < FXSYS_Mul(start_k, end_x) + start_c) { + start_outside_c += start_dc; + } else { + start_outside_c -= start_dc; + } + FX_FLOAT end_outside_c = end_c; + if (start_y < FXSYS_Mul(end_k, start_x) + end_c) { + end_outside_c += end_dc; + } else { + end_outside_c -= end_dc; + } + FX_FLOAT join_x = FXSYS_Div(end_outside_c - start_outside_c, start_k - end_k); + FX_FLOAT join_y = FXSYS_Mul(start_k, join_x) + start_outside_c; + rect.UpdateRect(join_x, join_y); +} +CFX_FloatRect CFX_PathData::GetBoundingBox(FX_FLOAT line_width, + FX_FLOAT miter_limit) const { + CFX_FloatRect rect(100000 * 1.0f, 100000 * 1.0f, -100000 * 1.0f, + -100000 * 1.0f); + int iPoint = 0; + FX_FLOAT half_width = line_width; + int iStartPoint, iEndPoint, iMiddlePoint; + FX_BOOL bJoin; + while (iPoint < m_PointCount) { + if (m_pPoints[iPoint].m_Flag == FXPT_MOVETO) { + iStartPoint = iPoint + 1; + iEndPoint = iPoint; + bJoin = FALSE; + } else { + if (m_pPoints[iPoint].m_Flag == FXPT_BEZIERTO) { + rect.UpdateRect(m_pPoints[iPoint].m_PointX, m_pPoints[iPoint].m_PointY); + rect.UpdateRect(m_pPoints[iPoint + 1].m_PointX, + m_pPoints[iPoint + 1].m_PointY); + iPoint += 2; + } + if (iPoint == m_PointCount - 1 || + m_pPoints[iPoint + 1].m_Flag == FXPT_MOVETO) { + iStartPoint = iPoint - 1; + iEndPoint = iPoint; + bJoin = FALSE; + } else { + iStartPoint = iPoint - 1; + iMiddlePoint = iPoint; + iEndPoint = iPoint + 1; + bJoin = TRUE; + } + } + FX_FLOAT start_x = m_pPoints[iStartPoint].m_PointX; + FX_FLOAT start_y = m_pPoints[iStartPoint].m_PointY; + FX_FLOAT end_x = m_pPoints[iEndPoint].m_PointX; + FX_FLOAT end_y = m_pPoints[iEndPoint].m_PointY; + if (bJoin) { + FX_FLOAT middle_x = m_pPoints[iMiddlePoint].m_PointX; + FX_FLOAT middle_y = m_pPoints[iMiddlePoint].m_PointY; + _UpdateLineJoinPoints(rect, start_x, start_y, middle_x, middle_y, end_x, + end_y, half_width, miter_limit); + } else { + _UpdateLineEndPoints(rect, start_x, start_y, end_x, end_y, half_width); + } + iPoint++; + } + return rect; +} +void CFX_PathData::Transform(const CFX_AffineMatrix* pMatrix) { + if (pMatrix == NULL) { + return; + } + for (int i = 0; i < m_PointCount; i++) { + pMatrix->Transform(m_pPoints[i].m_PointX, m_pPoints[i].m_PointY); + } +} +FX_BOOL CFX_PathData::GetZeroAreaPath(CFX_PathData& NewPath, + CFX_AffineMatrix* pMatrix, + FX_BOOL& bThin, + FX_BOOL bAdjust) const { + if (m_PointCount < 3) { + return FALSE; + } + if (m_PointCount == 3 && (m_pPoints[0].m_Flag & FXPT_TYPE) == FXPT_MOVETO && + (m_pPoints[1].m_Flag & FXPT_TYPE) == FXPT_LINETO && + (m_pPoints[2].m_Flag & FXPT_TYPE) == FXPT_LINETO && + m_pPoints[0].m_PointX == m_pPoints[2].m_PointX && + m_pPoints[0].m_PointY == m_pPoints[2].m_PointY) { + NewPath.AddPointCount(2); + if (bAdjust) { + if (pMatrix) { + FX_FLOAT x = m_pPoints[0].m_PointX, y = m_pPoints[0].m_PointY; + pMatrix->TransformPoint(x, y); + x = (int)x + 0.5f; + y = (int)y + 0.5f; + NewPath.SetPoint(0, x, y, FXPT_MOVETO); + x = m_pPoints[1].m_PointX, y = m_pPoints[1].m_PointY; + pMatrix->TransformPoint(x, y); + x = (int)x + 0.5f; + y = (int)y + 0.5f; + NewPath.SetPoint(1, x, y, FXPT_LINETO); + pMatrix->SetIdentity(); + } else { + FX_FLOAT x = (int)m_pPoints[0].m_PointX + 0.5f, + y = (int)m_pPoints[0].m_PointY + 0.5f; + NewPath.SetPoint(0, x, y, FXPT_MOVETO); + x = (int)m_pPoints[1].m_PointX + 0.5f, + y = (int)m_pPoints[1].m_PointY + 0.5f; + NewPath.SetPoint(1, x, y, FXPT_LINETO); + } + } else { + NewPath.SetPoint(0, m_pPoints[0].m_PointX, m_pPoints[0].m_PointY, + FXPT_MOVETO); + NewPath.SetPoint(1, m_pPoints[1].m_PointX, m_pPoints[1].m_PointY, + FXPT_LINETO); } - if (NewPath.GetPointCount() == 0) { - return FALSE; + if (m_pPoints[0].m_PointX != m_pPoints[1].m_PointX && + m_pPoints[0].m_PointY != m_pPoints[1].m_PointY) { + bThin = TRUE; } return TRUE; -} -FX_BOOL CFX_PathData::IsRect() const -{ - if (m_PointCount != 5 && m_PointCount != 4) { - return FALSE; - } - if ((m_PointCount == 5 && (m_pPoints[0].m_PointX != m_pPoints[4].m_PointX || - m_pPoints[0].m_PointY != m_pPoints[4].m_PointY)) || - (m_pPoints[0].m_PointX == m_pPoints[2].m_PointX && m_pPoints[0].m_PointY == m_pPoints[2].m_PointY) || - (m_pPoints[1].m_PointX == m_pPoints[3].m_PointX && m_pPoints[1].m_PointY == m_pPoints[3].m_PointY)) { - return FALSE; - } - if (m_pPoints[0].m_PointX != m_pPoints[3].m_PointX && m_pPoints[0].m_PointY != m_pPoints[3].m_PointY) { - return FALSE; - } - for (int i = 1; i < 4; i ++) { - if ((m_pPoints[i].m_Flag & FXPT_TYPE) != FXPT_LINETO) { - return FALSE; - } - if (m_pPoints[i].m_PointX != m_pPoints[i - 1].m_PointX && m_pPoints[i].m_PointY != m_pPoints[i - 1].m_PointY) { - return FALSE; - } - } - return m_PointCount == 5 || (m_pPoints[3].m_Flag & FXPT_CLOSEFIGURE); -} -FX_BOOL CFX_PathData::IsRect(const CFX_AffineMatrix* pMatrix, CFX_FloatRect* pRect) const -{ - if (pMatrix == NULL) { - if (!IsRect()) { - return FALSE; - } - if (pRect) { - pRect->left = m_pPoints[0].m_PointX; - pRect->right = m_pPoints[2].m_PointX; - pRect->bottom = m_pPoints[0].m_PointY; - pRect->top = m_pPoints[2].m_PointY; - pRect->Normalize(); - } - return TRUE; - } - if (m_PointCount != 5 && m_PointCount != 4) { - return FALSE; - } - if ((m_PointCount == 5 && (m_pPoints[0].m_PointX != m_pPoints[4].m_PointX || m_pPoints[0].m_PointY != m_pPoints[4].m_PointY)) || - (m_pPoints[1].m_PointX == m_pPoints[3].m_PointX && m_pPoints[1].m_PointY == m_pPoints[3].m_PointY)) { - return FALSE; - } - if (m_PointCount == 4 && m_pPoints[0].m_PointX != m_pPoints[3].m_PointX && m_pPoints[0].m_PointY != m_pPoints[3].m_PointY) { - return FALSE; - } - FX_FLOAT x[5], y[5]; - for (int i = 0; i < m_PointCount; i ++) { - pMatrix->Transform(m_pPoints[i].m_PointX, m_pPoints[i].m_PointY, x[i], y[i]); - if (i) { - if ((m_pPoints[i].m_Flag & FXPT_TYPE) != FXPT_LINETO) { - return FALSE; - } - if (x[i] != x[i - 1] && y[i] != y[i - 1]) { - return FALSE; - } + } + if (((m_PointCount > 3) && (m_PointCount % 2))) { + int mid = m_PointCount / 2; + FX_BOOL bZeroArea = FALSE; + CFX_PathData t_path; + for (int i = 0; i < mid; i++) { + if (!(m_pPoints[mid - i - 1].m_PointX == + m_pPoints[mid + i + 1].m_PointX && + m_pPoints[mid - i - 1].m_PointY == + m_pPoints[mid + i + 1].m_PointY && + ((m_pPoints[mid - i - 1].m_Flag & FXPT_TYPE) != FXPT_BEZIERTO && + (m_pPoints[mid + i + 1].m_Flag & FXPT_TYPE) != FXPT_BEZIERTO))) { + bZeroArea = TRUE; + break; + } + int new_count = t_path.GetPointCount(); + t_path.AddPointCount(2); + t_path.SetPoint(new_count, m_pPoints[mid - i].m_PointX, + m_pPoints[mid - i].m_PointY, FXPT_MOVETO); + t_path.SetPoint(new_count + 1, m_pPoints[mid - i - 1].m_PointX, + m_pPoints[mid - i - 1].m_PointY, FXPT_LINETO); + } + if (!bZeroArea) { + NewPath.Append(&t_path, NULL); + bThin = TRUE; + return TRUE; + } + } + int stratPoint = 0; + int next = 0, i; + for (i = 0; i < m_PointCount; i++) { + int point_type = m_pPoints[i].m_Flag & FXPT_TYPE; + if (point_type == FXPT_MOVETO) { + stratPoint = i; + } else if (point_type == FXPT_LINETO) { + next = (i + 1 - stratPoint) % (m_PointCount - stratPoint) + stratPoint; + if ((m_pPoints[next].m_Flag & FXPT_TYPE) != FXPT_BEZIERTO && + (m_pPoints[next].m_Flag & FXPT_TYPE) != FXPT_MOVETO) { + if ((m_pPoints[i - 1].m_PointX == m_pPoints[i].m_PointX && + m_pPoints[i].m_PointX == m_pPoints[next].m_PointX) && + ((m_pPoints[i].m_PointY - m_pPoints[i - 1].m_PointY) * + (m_pPoints[i].m_PointY - m_pPoints[next].m_PointY) > + 0)) { + int pre = i; + if (FXSYS_fabs(m_pPoints[i].m_PointY - m_pPoints[i - 1].m_PointY) < + FXSYS_fabs(m_pPoints[i].m_PointY - m_pPoints[next].m_PointY)) { + pre--; + next--; + } + int new_count = NewPath.GetPointCount(); + NewPath.AddPointCount(2); + NewPath.SetPoint(new_count, m_pPoints[pre].m_PointX, + m_pPoints[pre].m_PointY, FXPT_MOVETO); + NewPath.SetPoint(new_count + 1, m_pPoints[next].m_PointX, + m_pPoints[next].m_PointY, FXPT_LINETO); + } else if ((m_pPoints[i - 1].m_PointY == m_pPoints[i].m_PointY && + m_pPoints[i].m_PointY == m_pPoints[next].m_PointY) && + ((m_pPoints[i].m_PointX - m_pPoints[i - 1].m_PointX) * + (m_pPoints[i].m_PointX - m_pPoints[next].m_PointX) > + 0)) { + int pre = i; + if (FXSYS_fabs(m_pPoints[i].m_PointX - m_pPoints[i - 1].m_PointX) < + FXSYS_fabs(m_pPoints[i].m_PointX - m_pPoints[next].m_PointX)) { + pre--; + next--; + } + int new_count = NewPath.GetPointCount(); + NewPath.AddPointCount(2); + NewPath.SetPoint(new_count, m_pPoints[pre].m_PointX, + m_pPoints[pre].m_PointY, FXPT_MOVETO); + NewPath.SetPoint(new_count + 1, m_pPoints[next].m_PointX, + m_pPoints[next].m_PointY, FXPT_LINETO); + } else if ((m_pPoints[i - 1].m_Flag & FXPT_TYPE) == FXPT_MOVETO && + (m_pPoints[next].m_Flag & FXPT_TYPE) == FXPT_LINETO && + m_pPoints[i - 1].m_PointX == m_pPoints[next].m_PointX && + m_pPoints[i - 1].m_PointY == m_pPoints[next].m_PointY && + m_pPoints[next].m_Flag & FXPT_CLOSEFIGURE) { + int new_count = NewPath.GetPointCount(); + NewPath.AddPointCount(2); + NewPath.SetPoint(new_count, m_pPoints[i - 1].m_PointX, + m_pPoints[i - 1].m_PointY, FXPT_MOVETO); + NewPath.SetPoint(new_count + 1, m_pPoints[i].m_PointX, + m_pPoints[i].m_PointY, FXPT_LINETO); + bThin = TRUE; } + } + } else if (point_type == FXPT_BEZIERTO) { + i += 2; + continue; + } + } + if (m_PointCount > 3 && NewPath.GetPointCount()) { + bThin = TRUE; + } + if (NewPath.GetPointCount() == 0) { + return FALSE; + } + return TRUE; +} +FX_BOOL CFX_PathData::IsRect() const { + if (m_PointCount != 5 && m_PointCount != 4) { + return FALSE; + } + if ((m_PointCount == 5 && (m_pPoints[0].m_PointX != m_pPoints[4].m_PointX || + m_pPoints[0].m_PointY != m_pPoints[4].m_PointY)) || + (m_pPoints[0].m_PointX == m_pPoints[2].m_PointX && + m_pPoints[0].m_PointY == m_pPoints[2].m_PointY) || + (m_pPoints[1].m_PointX == m_pPoints[3].m_PointX && + m_pPoints[1].m_PointY == m_pPoints[3].m_PointY)) { + return FALSE; + } + if (m_pPoints[0].m_PointX != m_pPoints[3].m_PointX && + m_pPoints[0].m_PointY != m_pPoints[3].m_PointY) { + return FALSE; + } + for (int i = 1; i < 4; i++) { + if ((m_pPoints[i].m_Flag & FXPT_TYPE) != FXPT_LINETO) { + return FALSE; + } + if (m_pPoints[i].m_PointX != m_pPoints[i - 1].m_PointX && + m_pPoints[i].m_PointY != m_pPoints[i - 1].m_PointY) { + return FALSE; + } + } + return m_PointCount == 5 || (m_pPoints[3].m_Flag & FXPT_CLOSEFIGURE); +} +FX_BOOL CFX_PathData::IsRect(const CFX_AffineMatrix* pMatrix, + CFX_FloatRect* pRect) const { + if (pMatrix == NULL) { + if (!IsRect()) { + return FALSE; } if (pRect) { - pRect->left = x[0]; - pRect->right = x[2]; - pRect->bottom = y[0]; - pRect->top = y[2]; - pRect->Normalize(); + pRect->left = m_pPoints[0].m_PointX; + pRect->right = m_pPoints[2].m_PointX; + pRect->bottom = m_pPoints[0].m_PointY; + pRect->top = m_pPoints[2].m_PointY; + pRect->Normalize(); } return TRUE; -} -void CFX_PathData::Copy(const CFX_PathData &src) -{ - SetPointCount(src.m_PointCount); - FXSYS_memcpy(m_pPoints, src.m_pPoints, sizeof(FX_PATHPOINT) * m_PointCount); -} -CFX_GraphStateData::CFX_GraphStateData() -{ - m_LineCap = LineCapButt; - m_DashCount = 0; - m_DashArray = NULL; - m_DashPhase = 0; - m_LineJoin = LineJoinMiter; - m_MiterLimit = 10 * 1.0f; - m_LineWidth = 1.0f; -} -CFX_GraphStateData::CFX_GraphStateData(const CFX_GraphStateData& src) -{ - m_DashArray = NULL; - Copy(src); -} -void CFX_GraphStateData::Copy(const CFX_GraphStateData& src) -{ - m_LineCap = src.m_LineCap; - m_DashCount = src.m_DashCount; - if (m_DashArray) { - FX_Free(m_DashArray); - } - m_DashArray = NULL; - m_DashPhase = src.m_DashPhase; - m_LineJoin = src.m_LineJoin; - m_MiterLimit = src.m_MiterLimit; - m_LineWidth = src.m_LineWidth; - if (m_DashCount) { - m_DashArray = FX_Alloc(FX_FLOAT, m_DashCount); - FXSYS_memcpy(m_DashArray, src.m_DashArray, m_DashCount * sizeof(FX_FLOAT)); - } -} -CFX_GraphStateData::~CFX_GraphStateData() -{ - if (m_DashArray) { - FX_Free(m_DashArray); - } -} -void CFX_GraphStateData::SetDashCount(int count) -{ - if (m_DashArray) { - FX_Free(m_DashArray); - } - m_DashArray = NULL; - m_DashCount = count; - if (count == 0) { - return; - } - m_DashArray = FX_Alloc(FX_FLOAT, count); + } + if (m_PointCount != 5 && m_PointCount != 4) { + return FALSE; + } + if ((m_PointCount == 5 && (m_pPoints[0].m_PointX != m_pPoints[4].m_PointX || + m_pPoints[0].m_PointY != m_pPoints[4].m_PointY)) || + (m_pPoints[1].m_PointX == m_pPoints[3].m_PointX && + m_pPoints[1].m_PointY == m_pPoints[3].m_PointY)) { + return FALSE; + } + if (m_PointCount == 4 && m_pPoints[0].m_PointX != m_pPoints[3].m_PointX && + m_pPoints[0].m_PointY != m_pPoints[3].m_PointY) { + return FALSE; + } + FX_FLOAT x[5], y[5]; + for (int i = 0; i < m_PointCount; i++) { + pMatrix->Transform(m_pPoints[i].m_PointX, m_pPoints[i].m_PointY, x[i], + y[i]); + if (i) { + if ((m_pPoints[i].m_Flag & FXPT_TYPE) != FXPT_LINETO) { + return FALSE; + } + if (x[i] != x[i - 1] && y[i] != y[i - 1]) { + return FALSE; + } + } + } + if (pRect) { + pRect->left = x[0]; + pRect->right = x[2]; + pRect->bottom = y[0]; + pRect->top = y[2]; + pRect->Normalize(); + } + return TRUE; +} +void CFX_PathData::Copy(const CFX_PathData& src) { + SetPointCount(src.m_PointCount); + FXSYS_memcpy(m_pPoints, src.m_pPoints, sizeof(FX_PATHPOINT) * m_PointCount); +} +CFX_GraphStateData::CFX_GraphStateData() { + m_LineCap = LineCapButt; + m_DashCount = 0; + m_DashArray = NULL; + m_DashPhase = 0; + m_LineJoin = LineJoinMiter; + m_MiterLimit = 10 * 1.0f; + m_LineWidth = 1.0f; +} +CFX_GraphStateData::CFX_GraphStateData(const CFX_GraphStateData& src) { + m_DashArray = NULL; + Copy(src); +} +void CFX_GraphStateData::Copy(const CFX_GraphStateData& src) { + m_LineCap = src.m_LineCap; + m_DashCount = src.m_DashCount; + if (m_DashArray) { + FX_Free(m_DashArray); + } + m_DashArray = NULL; + m_DashPhase = src.m_DashPhase; + m_LineJoin = src.m_LineJoin; + m_MiterLimit = src.m_MiterLimit; + m_LineWidth = src.m_LineWidth; + if (m_DashCount) { + m_DashArray = FX_Alloc(FX_FLOAT, m_DashCount); + FXSYS_memcpy(m_DashArray, src.m_DashArray, m_DashCount * sizeof(FX_FLOAT)); + } +} +CFX_GraphStateData::~CFX_GraphStateData() { + if (m_DashArray) { + FX_Free(m_DashArray); + } +} +void CFX_GraphStateData::SetDashCount(int count) { + if (m_DashArray) { + FX_Free(m_DashArray); + } + m_DashArray = NULL; + m_DashCount = count; + if (count == 0) { + return; + } + m_DashArray = FX_Alloc(FX_FLOAT, count); } diff --git a/core/src/fxge/ge/fx_ge_ps.cpp b/core/src/fxge/ge/fx_ge_ps.cpp index ba5c5fbabb..d20825d458 100644 --- a/core/src/fxge/ge/fx_ge_ps.cpp +++ b/core/src/fxge/ge/fx_ge_ps.cpp @@ -8,172 +8,173 @@ #include "../../../include/fxcodec/fx_codec.h" #include "text_int.h" struct PSGlyph { - CFX_Font* m_pFont; - FX_DWORD m_GlyphIndex; - FX_BOOL m_bGlyphAdjust; - FX_FLOAT m_AdjustMatrix[4]; + CFX_Font* m_pFont; + FX_DWORD m_GlyphIndex; + FX_BOOL m_bGlyphAdjust; + FX_FLOAT m_AdjustMatrix[4]; }; -class CPSFont -{ -public: - PSGlyph m_Glyphs[256]; - int m_nGlyphs; +class CPSFont { + public: + PSGlyph m_Glyphs[256]; + int m_nGlyphs; }; -CFX_PSRenderer::CFX_PSRenderer() -{ - m_pOutput = NULL; - m_bColorSet = m_bGraphStateSet = FALSE; - m_bInited = FALSE; +CFX_PSRenderer::CFX_PSRenderer() { + m_pOutput = NULL; + m_bColorSet = m_bGraphStateSet = FALSE; + m_bInited = FALSE; } -CFX_PSRenderer::~CFX_PSRenderer() -{ - for (int i = 0; i < (int)m_PSFontList.GetSize(); i ++) { - CPSFont* pFont = m_PSFontList[i]; - delete pFont; - } +CFX_PSRenderer::~CFX_PSRenderer() { + for (int i = 0; i < (int)m_PSFontList.GetSize(); i++) { + CPSFont* pFont = m_PSFontList[i]; + delete pFont; + } } -#define OUTPUT_PS(str) m_pOutput->OutputPS(str, sizeof str-1) -void CFX_PSRenderer::Init(IFX_PSOutput* pOutput, int pslevel, int width, int height, FX_BOOL bCmykOutput) -{ - m_PSLevel = pslevel; - m_pOutput = pOutput; - m_ClipBox.left = m_ClipBox.top = 0; - m_ClipBox.right = width; - m_ClipBox.bottom = height; - m_bCmykOutput = bCmykOutput; +#define OUTPUT_PS(str) m_pOutput->OutputPS(str, sizeof str - 1) +void CFX_PSRenderer::Init(IFX_PSOutput* pOutput, + int pslevel, + int width, + int height, + FX_BOOL bCmykOutput) { + m_PSLevel = pslevel; + m_pOutput = pOutput; + m_ClipBox.left = m_ClipBox.top = 0; + m_ClipBox.right = width; + m_ClipBox.bottom = height; + m_bCmykOutput = bCmykOutput; } -FX_BOOL CFX_PSRenderer::StartRendering() -{ - if (m_bInited) { - return TRUE; - } - static const char init_str[] = "\nsave\n/im/initmatrix load def\n" - "/n/newpath load def/m/moveto load def/l/lineto load def/c/curveto load def/h/closepath load def\n" - "/f/fill load def/F/eofill load def/s/stroke load def/W/clip load def/W*/eoclip load def\n" - "/rg/setrgbcolor load def/k/setcmykcolor load def\n" - "/J/setlinecap load def/j/setlinejoin load def/w/setlinewidth load def/M/setmiterlimit load def/d/setdash load def\n" - "/q/gsave load def/Q/grestore load def/iM/imagemask load def\n" - "/Tj/show load def/Ff/findfont load def/Fs/scalefont load def/Sf/setfont load def\n" - "/cm/concat load def/Cm/currentmatrix load def/mx/matrix load def/sm/setmatrix load def\n" - ; - OUTPUT_PS(init_str); - m_bInited = TRUE; +FX_BOOL CFX_PSRenderer::StartRendering() { + if (m_bInited) { return TRUE; + } + static const char init_str[] = + "\nsave\n/im/initmatrix load def\n" + "/n/newpath load def/m/moveto load def/l/lineto load def/c/curveto load " + "def/h/closepath load def\n" + "/f/fill load def/F/eofill load def/s/stroke load def/W/clip load " + "def/W*/eoclip load def\n" + "/rg/setrgbcolor load def/k/setcmykcolor load def\n" + "/J/setlinecap load def/j/setlinejoin load def/w/setlinewidth load " + "def/M/setmiterlimit load def/d/setdash load def\n" + "/q/gsave load def/Q/grestore load def/iM/imagemask load def\n" + "/Tj/show load def/Ff/findfont load def/Fs/scalefont load def/Sf/setfont " + "load def\n" + "/cm/concat load def/Cm/currentmatrix load def/mx/matrix load " + "def/sm/setmatrix load def\n"; + OUTPUT_PS(init_str); + m_bInited = TRUE; + return TRUE; } -void CFX_PSRenderer::EndRendering() -{ - if (m_bInited) { - OUTPUT_PS("\nrestore\n"); - } - m_bInited = FALSE; +void CFX_PSRenderer::EndRendering() { + if (m_bInited) { + OUTPUT_PS("\nrestore\n"); + } + m_bInited = FALSE; } -void CFX_PSRenderer::SaveState() -{ - StartRendering(); - OUTPUT_PS("q\n"); - m_ClipBoxStack.Add(m_ClipBox); +void CFX_PSRenderer::SaveState() { + StartRendering(); + OUTPUT_PS("q\n"); + m_ClipBoxStack.Add(m_ClipBox); } -void CFX_PSRenderer::RestoreState(FX_BOOL bKeepSaved) -{ - StartRendering(); - if (bKeepSaved) { - OUTPUT_PS("Q\nq\n"); - } else { - OUTPUT_PS("Q\n"); - } - m_bColorSet = m_bGraphStateSet = FALSE; - m_ClipBox = m_ClipBoxStack.GetAt(m_ClipBoxStack.GetSize() - 1); - if (!bKeepSaved) { - m_ClipBoxStack.RemoveAt(m_ClipBoxStack.GetSize() - 1); - } +void CFX_PSRenderer::RestoreState(FX_BOOL bKeepSaved) { + StartRendering(); + if (bKeepSaved) { + OUTPUT_PS("Q\nq\n"); + } else { + OUTPUT_PS("Q\n"); + } + m_bColorSet = m_bGraphStateSet = FALSE; + m_ClipBox = m_ClipBoxStack.GetAt(m_ClipBoxStack.GetSize() - 1); + if (!bKeepSaved) { + m_ClipBoxStack.RemoveAt(m_ClipBoxStack.GetSize() - 1); + } } -void CFX_PSRenderer::OutputPath(const CFX_PathData* pPathData, const CFX_AffineMatrix* pObject2Device) -{ - int nPoints = pPathData->GetPointCount(); - CFX_ByteTextBuf buf; - buf.EstimateSize(nPoints * 10); - for (int i = 0; i < nPoints; i ++) { - uint8_t flag = pPathData->GetFlag(i); - FX_FLOAT x = pPathData->GetPointX(i); - FX_FLOAT y = pPathData->GetPointY(i); +void CFX_PSRenderer::OutputPath(const CFX_PathData* pPathData, + const CFX_AffineMatrix* pObject2Device) { + int nPoints = pPathData->GetPointCount(); + CFX_ByteTextBuf buf; + buf.EstimateSize(nPoints * 10); + for (int i = 0; i < nPoints; i++) { + uint8_t flag = pPathData->GetFlag(i); + FX_FLOAT x = pPathData->GetPointX(i); + FX_FLOAT y = pPathData->GetPointY(i); + if (pObject2Device) { + pObject2Device->Transform(x, y); + } + buf << x << FX_BSTRC(" ") << y; + switch (flag & FXPT_TYPE) { + case FXPT_MOVETO: + buf << FX_BSTRC(" m "); + break; + case FXPT_LINETO: + if (flag & FXPT_CLOSEFIGURE) { + buf << FX_BSTRC(" l h "); + } else { + buf << FX_BSTRC(" l "); + } + break; + case FXPT_BEZIERTO: { + FX_FLOAT x1 = pPathData->GetPointX(i + 1); + FX_FLOAT x2 = pPathData->GetPointX(i + 2); + FX_FLOAT y1 = pPathData->GetPointY(i + 1); + FX_FLOAT y2 = pPathData->GetPointY(i + 2); if (pObject2Device) { - pObject2Device->Transform(x, y); + pObject2Device->Transform(x1, y1); + pObject2Device->Transform(x2, y2); } - buf << x << FX_BSTRC(" ") << y; - switch (flag & FXPT_TYPE) { - case FXPT_MOVETO: - buf << FX_BSTRC(" m "); - break; - case FXPT_LINETO: - if (flag & FXPT_CLOSEFIGURE) { - buf << FX_BSTRC(" l h "); - } else { - buf << FX_BSTRC(" l "); - } - break; - case FXPT_BEZIERTO: { - FX_FLOAT x1 = pPathData->GetPointX(i + 1); - FX_FLOAT x2 = pPathData->GetPointX(i + 2); - FX_FLOAT y1 = pPathData->GetPointY(i + 1); - FX_FLOAT y2 = pPathData->GetPointY(i + 2); - if (pObject2Device) { - pObject2Device->Transform(x1, y1); - pObject2Device->Transform(x2, y2); - } - buf << FX_BSTRC(" ") << x1 << FX_BSTRC(" ") << y1 << FX_BSTRC(" ") << x2 << FX_BSTRC(" ") << y2; - if (flag & FXPT_CLOSEFIGURE) { - buf << FX_BSTRC(" c h\n"); - } else { - buf << FX_BSTRC(" c\n"); - } - i += 2; - break; - } + buf << FX_BSTRC(" ") << x1 << FX_BSTRC(" ") << y1 << FX_BSTRC(" ") << x2 + << FX_BSTRC(" ") << y2; + if (flag & FXPT_CLOSEFIGURE) { + buf << FX_BSTRC(" c h\n"); + } else { + buf << FX_BSTRC(" c\n"); } + i += 2; + break; + } } - m_pOutput->OutputPS((const FX_CHAR*)buf.GetBuffer(), buf.GetSize()); + } + m_pOutput->OutputPS((const FX_CHAR*)buf.GetBuffer(), buf.GetSize()); } void CFX_PSRenderer::SetClip_PathFill(const CFX_PathData* pPathData, const CFX_AffineMatrix* pObject2Device, - int fill_mode - ) -{ - StartRendering(); - OutputPath(pPathData, pObject2Device); - CFX_FloatRect rect = pPathData->GetBoundingBox(); - if (pObject2Device) { - rect.Transform(pObject2Device); - } - m_ClipBox.Intersect(rect.GetOutterRect()); - if ((fill_mode & 3) == FXFILL_WINDING) { - OUTPUT_PS("W n\n"); - } else { - OUTPUT_PS("W* n\n"); - } + int fill_mode) { + StartRendering(); + OutputPath(pPathData, pObject2Device); + CFX_FloatRect rect = pPathData->GetBoundingBox(); + if (pObject2Device) { + rect.Transform(pObject2Device); + } + m_ClipBox.Intersect(rect.GetOutterRect()); + if ((fill_mode & 3) == FXFILL_WINDING) { + OUTPUT_PS("W n\n"); + } else { + OUTPUT_PS("W* n\n"); + } } void CFX_PSRenderer::SetClip_PathStroke(const CFX_PathData* pPathData, const CFX_AffineMatrix* pObject2Device, - const CFX_GraphStateData* pGraphState - ) -{ - StartRendering(); - SetGraphState(pGraphState); - if (pObject2Device) { - CFX_ByteTextBuf buf; - buf << FX_BSTRC("mx Cm [") << pObject2Device->a << FX_BSTRC(" ") << pObject2Device->b << FX_BSTRC(" ") << - pObject2Device->c << FX_BSTRC(" ") << pObject2Device->d << FX_BSTRC(" ") << pObject2Device->e << - FX_BSTRC(" ") << pObject2Device->f << FX_BSTRC("]cm "); - m_pOutput->OutputPS((const FX_CHAR*)buf.GetBuffer(), buf.GetSize()); - } - OutputPath(pPathData, NULL); - CFX_FloatRect rect = pPathData->GetBoundingBox(pGraphState->m_LineWidth, pGraphState->m_MiterLimit); - rect.Transform(pObject2Device); - m_ClipBox.Intersect(rect.GetOutterRect()); - if (pObject2Device) { - OUTPUT_PS("strokepath W n sm\n"); - } else { - OUTPUT_PS("strokepath W n\n"); - } + const CFX_GraphStateData* pGraphState) { + StartRendering(); + SetGraphState(pGraphState); + if (pObject2Device) { + CFX_ByteTextBuf buf; + buf << FX_BSTRC("mx Cm [") << pObject2Device->a << FX_BSTRC(" ") + << pObject2Device->b << FX_BSTRC(" ") << pObject2Device->c + << FX_BSTRC(" ") << pObject2Device->d << FX_BSTRC(" ") + << pObject2Device->e << FX_BSTRC(" ") << pObject2Device->f + << FX_BSTRC("]cm "); + m_pOutput->OutputPS((const FX_CHAR*)buf.GetBuffer(), buf.GetSize()); + } + OutputPath(pPathData, NULL); + CFX_FloatRect rect = pPathData->GetBoundingBox(pGraphState->m_LineWidth, + pGraphState->m_MiterLimit); + rect.Transform(pObject2Device); + m_ClipBox.Intersect(rect.GetOutterRect()); + if (pObject2Device) { + OUTPUT_PS("strokepath W n sm\n"); + } else { + OUTPUT_PS("strokepath W n\n"); + } } FX_BOOL CFX_PSRenderer::DrawPath(const CFX_PathData* pPathData, const CFX_AffineMatrix* pObject2Device, @@ -182,463 +183,536 @@ FX_BOOL CFX_PSRenderer::DrawPath(const CFX_PathData* pPathData, FX_DWORD stroke_color, int fill_mode, int alpha_flag, - void* pIccTransform - ) -{ - StartRendering(); - int fill_alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(fill_color); - int stroke_alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_STROKE(alpha_flag) : FXARGB_A(stroke_color); - if (fill_alpha && fill_alpha < 255) { - return FALSE; - } - if (stroke_alpha && stroke_alpha < 255) { - return FALSE; - } - if (fill_alpha == 0 && stroke_alpha == 0) { - return FALSE; - } - if (stroke_alpha) { - SetGraphState(pGraphState); - if (pObject2Device) { - CFX_ByteTextBuf buf; - buf << FX_BSTRC("mx Cm [") << pObject2Device->a << FX_BSTRC(" ") << pObject2Device->b << FX_BSTRC(" ") << - pObject2Device->c << FX_BSTRC(" ") << pObject2Device->d << FX_BSTRC(" ") << pObject2Device->e << - FX_BSTRC(" ") << pObject2Device->f << FX_BSTRC("]cm "); - m_pOutput->OutputPS((const FX_CHAR*)buf.GetBuffer(), buf.GetSize()); - } - } - OutputPath(pPathData, stroke_alpha ? NULL : pObject2Device); - if (fill_mode && fill_alpha) { - SetColor(fill_color, alpha_flag, pIccTransform); - if ((fill_mode & 3) == FXFILL_WINDING) { - if (stroke_alpha) { - OUTPUT_PS("q f Q "); - } else { - OUTPUT_PS("f"); - } - } else if ((fill_mode & 3) == FXFILL_ALTERNATE) { - if (stroke_alpha) { - OUTPUT_PS("q F Q "); - } else { - OUTPUT_PS("F"); - } - } - } - if (stroke_alpha) { - SetColor(stroke_color, alpha_flag, pIccTransform); - if (pObject2Device) { - OUTPUT_PS("s sm"); - } else { - OUTPUT_PS("s"); - } + void* pIccTransform) { + StartRendering(); + int fill_alpha = FXGETFLAG_COLORTYPE(alpha_flag) + ? FXGETFLAG_ALPHA_FILL(alpha_flag) + : FXARGB_A(fill_color); + int stroke_alpha = FXGETFLAG_COLORTYPE(alpha_flag) + ? FXGETFLAG_ALPHA_STROKE(alpha_flag) + : FXARGB_A(stroke_color); + if (fill_alpha && fill_alpha < 255) { + return FALSE; + } + if (stroke_alpha && stroke_alpha < 255) { + return FALSE; + } + if (fill_alpha == 0 && stroke_alpha == 0) { + return FALSE; + } + if (stroke_alpha) { + SetGraphState(pGraphState); + if (pObject2Device) { + CFX_ByteTextBuf buf; + buf << FX_BSTRC("mx Cm [") << pObject2Device->a << FX_BSTRC(" ") + << pObject2Device->b << FX_BSTRC(" ") << pObject2Device->c + << FX_BSTRC(" ") << pObject2Device->d << FX_BSTRC(" ") + << pObject2Device->e << FX_BSTRC(" ") << pObject2Device->f + << FX_BSTRC("]cm "); + m_pOutput->OutputPS((const FX_CHAR*)buf.GetBuffer(), buf.GetSize()); + } + } + OutputPath(pPathData, stroke_alpha ? NULL : pObject2Device); + if (fill_mode && fill_alpha) { + SetColor(fill_color, alpha_flag, pIccTransform); + if ((fill_mode & 3) == FXFILL_WINDING) { + if (stroke_alpha) { + OUTPUT_PS("q f Q "); + } else { + OUTPUT_PS("f"); + } + } else if ((fill_mode & 3) == FXFILL_ALTERNATE) { + if (stroke_alpha) { + OUTPUT_PS("q F Q "); + } else { + OUTPUT_PS("F"); + } + } + } + if (stroke_alpha) { + SetColor(stroke_color, alpha_flag, pIccTransform); + if (pObject2Device) { + OUTPUT_PS("s sm"); + } else { + OUTPUT_PS("s"); } - OUTPUT_PS("\n"); - return TRUE; + } + OUTPUT_PS("\n"); + return TRUE; } -void CFX_PSRenderer::SetGraphState(const CFX_GraphStateData* pGraphState) -{ - CFX_ByteTextBuf buf; - if (!m_bGraphStateSet || m_CurGraphState.m_LineCap != pGraphState->m_LineCap) { - buf << pGraphState->m_LineCap << FX_BSTRC(" J\n"); - } - if (!m_bGraphStateSet || m_CurGraphState.m_DashCount != pGraphState->m_DashCount || - FXSYS_memcmp(m_CurGraphState.m_DashArray, pGraphState->m_DashArray, sizeof(FX_FLOAT)*m_CurGraphState.m_DashCount)) { - buf << FX_BSTRC("["); - for (int i = 0; i < pGraphState->m_DashCount; i ++) { - buf << pGraphState->m_DashArray[i] << FX_BSTRC(" "); - } - buf << FX_BSTRC("]") << pGraphState->m_DashPhase << FX_BSTRC(" d\n"); - } - if (!m_bGraphStateSet || m_CurGraphState.m_LineJoin != pGraphState->m_LineJoin) { - buf << pGraphState->m_LineJoin << FX_BSTRC(" j\n"); - } - if (!m_bGraphStateSet || m_CurGraphState.m_LineWidth != pGraphState->m_LineWidth) { - buf << pGraphState->m_LineWidth << FX_BSTRC(" w\n"); - } - if (!m_bGraphStateSet || m_CurGraphState.m_MiterLimit != pGraphState->m_MiterLimit) { - buf << pGraphState->m_MiterLimit << FX_BSTRC(" M\n"); - } - m_CurGraphState.Copy(*pGraphState); - m_bGraphStateSet = TRUE; - if (buf.GetSize()) { - m_pOutput->OutputPS((const FX_CHAR*)buf.GetBuffer(), buf.GetSize()); - } +void CFX_PSRenderer::SetGraphState(const CFX_GraphStateData* pGraphState) { + CFX_ByteTextBuf buf; + if (!m_bGraphStateSet || + m_CurGraphState.m_LineCap != pGraphState->m_LineCap) { + buf << pGraphState->m_LineCap << FX_BSTRC(" J\n"); + } + if (!m_bGraphStateSet || + m_CurGraphState.m_DashCount != pGraphState->m_DashCount || + FXSYS_memcmp(m_CurGraphState.m_DashArray, pGraphState->m_DashArray, + sizeof(FX_FLOAT) * m_CurGraphState.m_DashCount)) { + buf << FX_BSTRC("["); + for (int i = 0; i < pGraphState->m_DashCount; i++) { + buf << pGraphState->m_DashArray[i] << FX_BSTRC(" "); + } + buf << FX_BSTRC("]") << pGraphState->m_DashPhase << FX_BSTRC(" d\n"); + } + if (!m_bGraphStateSet || + m_CurGraphState.m_LineJoin != pGraphState->m_LineJoin) { + buf << pGraphState->m_LineJoin << FX_BSTRC(" j\n"); + } + if (!m_bGraphStateSet || + m_CurGraphState.m_LineWidth != pGraphState->m_LineWidth) { + buf << pGraphState->m_LineWidth << FX_BSTRC(" w\n"); + } + if (!m_bGraphStateSet || + m_CurGraphState.m_MiterLimit != pGraphState->m_MiterLimit) { + buf << pGraphState->m_MiterLimit << FX_BSTRC(" M\n"); + } + m_CurGraphState.Copy(*pGraphState); + m_bGraphStateSet = TRUE; + if (buf.GetSize()) { + m_pOutput->OutputPS((const FX_CHAR*)buf.GetBuffer(), buf.GetSize()); + } } -static void FaxCompressData(uint8_t* src_buf, int width, int height, uint8_t*& dest_buf, FX_DWORD& dest_size) -{ - CCodec_ModuleMgr* pEncoders = CFX_GEModule::Get()->GetCodecModule(); - if (width * height > 128 && pEncoders && pEncoders->GetFaxModule()->Encode(src_buf, width, height, (width + 7) / 8, dest_buf, dest_size)) { - FX_Free(src_buf); - } else { - dest_buf = src_buf; - dest_size = (width + 7) / 8 * height; - } +static void FaxCompressData(uint8_t* src_buf, + int width, + int height, + uint8_t*& dest_buf, + FX_DWORD& dest_size) { + CCodec_ModuleMgr* pEncoders = CFX_GEModule::Get()->GetCodecModule(); + if (width * height > 128 && pEncoders && + pEncoders->GetFaxModule()->Encode(src_buf, width, height, (width + 7) / 8, + dest_buf, dest_size)) { + FX_Free(src_buf); + } else { + dest_buf = src_buf; + dest_size = (width + 7) / 8 * height; + } } -static void PSCompressData(int PSLevel, uint8_t* src_buf, FX_DWORD src_size, - uint8_t*& output_buf, FX_DWORD& output_size, const FX_CHAR*& filter) -{ - output_buf = src_buf; - output_size = src_size; - filter = ""; - if (src_size < 1024) { - return; - } - CCodec_ModuleMgr* pEncoders = CFX_GEModule::Get()->GetCodecModule(); - uint8_t* dest_buf = NULL; - FX_DWORD dest_size = src_size; - if (PSLevel >= 3) { - if (pEncoders && pEncoders->GetFlateModule()->Encode(src_buf, src_size, dest_buf, dest_size)) { - filter = "/FlateDecode filter "; - } - } else { - if (pEncoders && pEncoders->GetBasicModule()->RunLengthEncode(src_buf, src_size, dest_buf, dest_size)) { - filter = "/RunLengthDecode filter "; - } - } - if (dest_size < src_size) { - output_buf = dest_buf; - output_size = dest_size; - } else { - filter = NULL; - if (dest_buf) { - FX_Free(dest_buf); - } - } +static void PSCompressData(int PSLevel, + uint8_t* src_buf, + FX_DWORD src_size, + uint8_t*& output_buf, + FX_DWORD& output_size, + const FX_CHAR*& filter) { + output_buf = src_buf; + output_size = src_size; + filter = ""; + if (src_size < 1024) { + return; + } + CCodec_ModuleMgr* pEncoders = CFX_GEModule::Get()->GetCodecModule(); + uint8_t* dest_buf = NULL; + FX_DWORD dest_size = src_size; + if (PSLevel >= 3) { + if (pEncoders && + pEncoders->GetFlateModule()->Encode(src_buf, src_size, dest_buf, + dest_size)) { + filter = "/FlateDecode filter "; + } + } else { + if (pEncoders && + pEncoders->GetBasicModule()->RunLengthEncode(src_buf, src_size, + dest_buf, dest_size)) { + filter = "/RunLengthDecode filter "; + } + } + if (dest_size < src_size) { + output_buf = dest_buf; + output_size = dest_size; + } else { + filter = NULL; + if (dest_buf) { + FX_Free(dest_buf); + } + } } -FX_BOOL CFX_PSRenderer::SetDIBits(const CFX_DIBSource* pSource, FX_DWORD color, int left, int top, - int alpha_flag, void* pIccTransform) -{ - StartRendering(); - CFX_AffineMatrix matrix((FX_FLOAT)(pSource->GetWidth()), 0.0f, 0.0f, -(FX_FLOAT)(pSource->GetHeight()), - (FX_FLOAT)(left), (FX_FLOAT)(top + pSource->GetHeight())); - return DrawDIBits(pSource, color, &matrix, 0, alpha_flag, pIccTransform); +FX_BOOL CFX_PSRenderer::SetDIBits(const CFX_DIBSource* pSource, + FX_DWORD color, + int left, + int top, + int alpha_flag, + void* pIccTransform) { + StartRendering(); + CFX_AffineMatrix matrix((FX_FLOAT)(pSource->GetWidth()), 0.0f, 0.0f, + -(FX_FLOAT)(pSource->GetHeight()), (FX_FLOAT)(left), + (FX_FLOAT)(top + pSource->GetHeight())); + return DrawDIBits(pSource, color, &matrix, 0, alpha_flag, pIccTransform); } -FX_BOOL CFX_PSRenderer::StretchDIBits(const CFX_DIBSource* pSource, FX_DWORD color, int dest_left, int dest_top, - int dest_width, int dest_height, FX_DWORD flags, - int alpha_flag, void* pIccTransform) -{ - StartRendering(); - CFX_AffineMatrix matrix((FX_FLOAT)(dest_width), 0.0f, 0.0f, (FX_FLOAT)(-dest_height), - (FX_FLOAT)(dest_left), (FX_FLOAT)(dest_top + dest_height)); - return DrawDIBits(pSource, color, &matrix, flags, alpha_flag, pIccTransform); +FX_BOOL CFX_PSRenderer::StretchDIBits(const CFX_DIBSource* pSource, + FX_DWORD color, + int dest_left, + int dest_top, + int dest_width, + int dest_height, + FX_DWORD flags, + int alpha_flag, + void* pIccTransform) { + StartRendering(); + CFX_AffineMatrix matrix((FX_FLOAT)(dest_width), 0.0f, 0.0f, + (FX_FLOAT)(-dest_height), (FX_FLOAT)(dest_left), + (FX_FLOAT)(dest_top + dest_height)); + return DrawDIBits(pSource, color, &matrix, flags, alpha_flag, pIccTransform); } -FX_BOOL CFX_PSRenderer::DrawDIBits(const CFX_DIBSource* pSource, FX_DWORD color, - const CFX_AffineMatrix* pMatrix, FX_DWORD flags, - int alpha_flag, void* pIccTransform) -{ - StartRendering(); - if ((pMatrix->a == 0 && pMatrix->b == 0) || (pMatrix->c == 0 && pMatrix->d == 0)) { - return TRUE; - } - if (pSource->HasAlpha()) { - return FALSE; - } - int alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_FILL(color) : FXARGB_A(color); - if (pSource->IsAlphaMask() && (alpha < 255 || pSource->GetBPP() != 1)) { - return FALSE; - } - OUTPUT_PS("q\n"); - CFX_ByteTextBuf buf; - buf << FX_BSTRC("[") << pMatrix->a << FX_BSTRC(" ") << pMatrix->b << FX_BSTRC(" ") << - pMatrix->c << FX_BSTRC(" ") << pMatrix->d << FX_BSTRC(" ") << pMatrix->e << - FX_BSTRC(" ") << pMatrix->f << FX_BSTRC("]cm "); - int width = pSource->GetWidth(); - int height = pSource->GetHeight(); - buf << width << FX_BSTRC(" ") << height; - if (pSource->GetBPP() == 1 && pSource->GetPalette() == NULL) { - int pitch = (width + 7) / 8; - FX_DWORD src_size = height * pitch; - uint8_t* src_buf = FX_Alloc(uint8_t, src_size); - for (int row = 0; row < height; row ++) { - const uint8_t* src_scan = pSource->GetScanline(row); - FXSYS_memcpy(src_buf + row * pitch, src_scan, pitch); - } - uint8_t* output_buf; - FX_DWORD output_size; - FaxCompressData(src_buf, width, height, output_buf, output_size); - if (pSource->IsAlphaMask()) { - SetColor(color, alpha_flag, pIccTransform); - m_bColorSet = FALSE; - buf << FX_BSTRC(" true["); - } else { - buf << FX_BSTRC(" 1["); - } - buf << width << FX_BSTRC(" 0 0 -") << height << FX_BSTRC(" 0 ") << height << - FX_BSTRC("]currentfile/ASCII85Decode filter "); - if (output_buf != src_buf) - buf << FX_BSTRC("<>/CCITTFaxDecode filter "); - if (pSource->IsAlphaMask()) { - buf << FX_BSTRC("iM\n"); - } else { - buf << FX_BSTRC("false 1 colorimage\n"); - } - m_pOutput->OutputPS((const FX_CHAR*)buf.GetBuffer(), buf.GetSize()); - WritePSBinary(output_buf, output_size); - FX_Free(output_buf); - } else { - CFX_DIBSource* pConverted = (CFX_DIBSource*)pSource; - if (pIccTransform) { - FXDIB_Format format = m_bCmykOutput ? FXDIB_Cmyk : FXDIB_Rgb; - pConverted = pSource->CloneConvert(format, NULL, pIccTransform); - } else { - switch (pSource->GetFormat()) { - case FXDIB_1bppRgb: - case FXDIB_Rgb32: - pConverted = pSource->CloneConvert(FXDIB_Rgb); - break; - case FXDIB_8bppRgb: - if (pSource->GetPalette() != NULL) { - pConverted = pSource->CloneConvert(FXDIB_Rgb); - } - break; - case FXDIB_1bppCmyk: - pConverted = pSource->CloneConvert(FXDIB_Cmyk); - break; - case FXDIB_8bppCmyk: - if (pSource->GetPalette() != NULL) { - pConverted = pSource->CloneConvert(FXDIB_Cmyk); - } - break; - default: - break; - } - } - if (pConverted == NULL) { - OUTPUT_PS("\nQ\n"); - return FALSE; - } - int Bpp = pConverted->GetBPP() / 8; - uint8_t* output_buf = NULL; - FX_STRSIZE output_size = 0; - const FX_CHAR* filter = NULL; - if (flags & FXRENDER_IMAGE_LOSSY) { - CCodec_ModuleMgr* pEncoders = CFX_GEModule::Get()->GetCodecModule(); - if (pEncoders && pEncoders->GetJpegModule()->Encode(pConverted, output_buf, output_size)) { - filter = "/DCTDecode filter "; - } - } - if (filter == NULL) { - int src_pitch = width * Bpp; - output_size = height * src_pitch; - output_buf = FX_Alloc(uint8_t, output_size); - for (int row = 0; row < height; row ++) { - const uint8_t* src_scan = pConverted->GetScanline(row); - uint8_t* dest_scan = output_buf + row * src_pitch; - if (Bpp == 3) { - for (int col = 0; col < width; col ++) { - *dest_scan++ = src_scan[2]; - *dest_scan++ = src_scan[1]; - *dest_scan++ = *src_scan; - src_scan += 3; - } - } else { - FXSYS_memcpy(dest_scan, src_scan, src_pitch); - } - } - uint8_t* compressed_buf; - FX_DWORD compressed_size; - PSCompressData(m_PSLevel, output_buf, output_size, compressed_buf, compressed_size, filter); - if (output_buf != compressed_buf) { - FX_Free(output_buf); - } - output_buf = compressed_buf; - output_size = compressed_size; - } - if (pConverted != pSource) { - delete pConverted; - pConverted = NULL; - } - buf << FX_BSTRC(" 8["); - buf << width << FX_BSTRC(" 0 0 -") << height << FX_BSTRC(" 0 ") << height << FX_BSTRC("]"); - buf << FX_BSTRC("currentfile/ASCII85Decode filter "); - if (filter) { - buf << filter; - } - buf << FX_BSTRC("false ") << Bpp; - buf << FX_BSTRC(" colorimage\n"); - m_pOutput->OutputPS((const FX_CHAR*)buf.GetBuffer(), buf.GetSize()); - WritePSBinary(output_buf, output_size); - FX_Free(output_buf); - } - OUTPUT_PS("\nQ\n"); +FX_BOOL CFX_PSRenderer::DrawDIBits(const CFX_DIBSource* pSource, + FX_DWORD color, + const CFX_AffineMatrix* pMatrix, + FX_DWORD flags, + int alpha_flag, + void* pIccTransform) { + StartRendering(); + if ((pMatrix->a == 0 && pMatrix->b == 0) || + (pMatrix->c == 0 && pMatrix->d == 0)) { return TRUE; -} -void CFX_PSRenderer::SetColor(FX_DWORD color, int alpha_flag, void* pIccTransform) -{ - if (!CFX_GEModule::Get()->GetCodecModule() || !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) { - pIccTransform = NULL; + } + if (pSource->HasAlpha()) { + return FALSE; + } + int alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_FILL(color) + : FXARGB_A(color); + if (pSource->IsAlphaMask() && (alpha < 255 || pSource->GetBPP() != 1)) { + return FALSE; + } + OUTPUT_PS("q\n"); + CFX_ByteTextBuf buf; + buf << FX_BSTRC("[") << pMatrix->a << FX_BSTRC(" ") << pMatrix->b + << FX_BSTRC(" ") << pMatrix->c << FX_BSTRC(" ") << pMatrix->d + << FX_BSTRC(" ") << pMatrix->e << FX_BSTRC(" ") << pMatrix->f + << FX_BSTRC("]cm "); + int width = pSource->GetWidth(); + int height = pSource->GetHeight(); + buf << width << FX_BSTRC(" ") << height; + if (pSource->GetBPP() == 1 && pSource->GetPalette() == NULL) { + int pitch = (width + 7) / 8; + FX_DWORD src_size = height * pitch; + uint8_t* src_buf = FX_Alloc(uint8_t, src_size); + for (int row = 0; row < height; row++) { + const uint8_t* src_scan = pSource->GetScanline(row); + FXSYS_memcpy(src_buf + row * pitch, src_scan, pitch); + } + uint8_t* output_buf; + FX_DWORD output_size; + FaxCompressData(src_buf, width, height, output_buf, output_size); + if (pSource->IsAlphaMask()) { + SetColor(color, alpha_flag, pIccTransform); + m_bColorSet = FALSE; + buf << FX_BSTRC(" true["); + } else { + buf << FX_BSTRC(" 1["); + } + buf << width << FX_BSTRC(" 0 0 -") << height << FX_BSTRC(" 0 ") << height + << FX_BSTRC("]currentfile/ASCII85Decode filter "); + if (output_buf != src_buf) + buf << FX_BSTRC("<>/CCITTFaxDecode filter "); + if (pSource->IsAlphaMask()) { + buf << FX_BSTRC("iM\n"); + } else { + buf << FX_BSTRC("false 1 colorimage\n"); } - FX_BOOL bCMYK = FALSE; + m_pOutput->OutputPS((const FX_CHAR*)buf.GetBuffer(), buf.GetSize()); + WritePSBinary(output_buf, output_size); + FX_Free(output_buf); + } else { + CFX_DIBSource* pConverted = (CFX_DIBSource*)pSource; if (pIccTransform) { - ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - color = FXGETFLAG_COLORTYPE(alpha_flag) ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); - uint8_t* pColor = (uint8_t*)&color; - pIccModule->TranslateScanline(pIccTransform, pColor, pColor, 1); - color = m_bCmykOutput ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); - bCMYK = m_bCmykOutput; + FXDIB_Format format = m_bCmykOutput ? FXDIB_Cmyk : FXDIB_Rgb; + pConverted = pSource->CloneConvert(format, NULL, pIccTransform); } else { - bCMYK = FXGETFLAG_COLORTYPE(alpha_flag); - } - if (bCMYK != m_bCmykOutput || !m_bColorSet || m_LastColor != color) { - CFX_ByteTextBuf buf; - if (bCMYK) { - buf << FXSYS_GetCValue(color) / 255.0 << FX_BSTRC(" ") << FXSYS_GetMValue(color) / 255.0 << FX_BSTRC(" ") - << FXSYS_GetYValue(color) / 255.0 << FX_BSTRC(" ") << FXSYS_GetKValue(color) / 255.0 << FX_BSTRC(" k\n"); + switch (pSource->GetFormat()) { + case FXDIB_1bppRgb: + case FXDIB_Rgb32: + pConverted = pSource->CloneConvert(FXDIB_Rgb); + break; + case FXDIB_8bppRgb: + if (pSource->GetPalette() != NULL) { + pConverted = pSource->CloneConvert(FXDIB_Rgb); + } + break; + case FXDIB_1bppCmyk: + pConverted = pSource->CloneConvert(FXDIB_Cmyk); + break; + case FXDIB_8bppCmyk: + if (pSource->GetPalette() != NULL) { + pConverted = pSource->CloneConvert(FXDIB_Cmyk); + } + break; + default: + break; + } + } + if (pConverted == NULL) { + OUTPUT_PS("\nQ\n"); + return FALSE; + } + int Bpp = pConverted->GetBPP() / 8; + uint8_t* output_buf = NULL; + FX_STRSIZE output_size = 0; + const FX_CHAR* filter = NULL; + if (flags & FXRENDER_IMAGE_LOSSY) { + CCodec_ModuleMgr* pEncoders = CFX_GEModule::Get()->GetCodecModule(); + if (pEncoders && + pEncoders->GetJpegModule()->Encode(pConverted, output_buf, + output_size)) { + filter = "/DCTDecode filter "; + } + } + if (filter == NULL) { + int src_pitch = width * Bpp; + output_size = height * src_pitch; + output_buf = FX_Alloc(uint8_t, output_size); + for (int row = 0; row < height; row++) { + const uint8_t* src_scan = pConverted->GetScanline(row); + uint8_t* dest_scan = output_buf + row * src_pitch; + if (Bpp == 3) { + for (int col = 0; col < width; col++) { + *dest_scan++ = src_scan[2]; + *dest_scan++ = src_scan[1]; + *dest_scan++ = *src_scan; + src_scan += 3; + } } else { - buf << FXARGB_R(color) / 255.0 << FX_BSTRC(" ") << FXARGB_G(color) / 255.0 << FX_BSTRC(" ") - << FXARGB_B(color) / 255.0 << FX_BSTRC(" rg\n"); + FXSYS_memcpy(dest_scan, src_scan, src_pitch); } - if (bCMYK == m_bCmykOutput) { - m_bColorSet = TRUE; - m_LastColor = color; - } - m_pOutput->OutputPS((const FX_CHAR*)buf.GetBuffer(), buf.GetSize()); - } + } + uint8_t* compressed_buf; + FX_DWORD compressed_size; + PSCompressData(m_PSLevel, output_buf, output_size, compressed_buf, + compressed_size, filter); + if (output_buf != compressed_buf) { + FX_Free(output_buf); + } + output_buf = compressed_buf; + output_size = compressed_size; + } + if (pConverted != pSource) { + delete pConverted; + pConverted = NULL; + } + buf << FX_BSTRC(" 8["); + buf << width << FX_BSTRC(" 0 0 -") << height << FX_BSTRC(" 0 ") << height + << FX_BSTRC("]"); + buf << FX_BSTRC("currentfile/ASCII85Decode filter "); + if (filter) { + buf << filter; + } + buf << FX_BSTRC("false ") << Bpp; + buf << FX_BSTRC(" colorimage\n"); + m_pOutput->OutputPS((const FX_CHAR*)buf.GetBuffer(), buf.GetSize()); + WritePSBinary(output_buf, output_size); + FX_Free(output_buf); + } + OUTPUT_PS("\nQ\n"); + return TRUE; } -void CFX_PSRenderer::FindPSFontGlyph(CFX_FaceCache* pFaceCache, CFX_Font* pFont, const FXTEXT_CHARPOS& charpos, - int& ps_fontnum, int &ps_glyphindex) -{ - for (int i = 0; i < (int)m_PSFontList.GetSize(); i ++) { - CPSFont* pPSFont = m_PSFontList[i]; - for (int j = 0; j < pPSFont->m_nGlyphs; j ++) - if (pPSFont->m_Glyphs[j].m_pFont == pFont && pPSFont->m_Glyphs[j].m_GlyphIndex == charpos.m_GlyphIndex) { - if ((!pPSFont->m_Glyphs[j].m_bGlyphAdjust && !charpos.m_bGlyphAdjust) || - (pPSFont->m_Glyphs[j].m_bGlyphAdjust && charpos.m_bGlyphAdjust && - (FXSYS_fabs(pPSFont->m_Glyphs[j].m_AdjustMatrix[0] - charpos.m_AdjustMatrix[0]) < 0.01 && - FXSYS_fabs(pPSFont->m_Glyphs[j].m_AdjustMatrix[1] - charpos.m_AdjustMatrix[1]) < 0.01 && - FXSYS_fabs(pPSFont->m_Glyphs[j].m_AdjustMatrix[2] - charpos.m_AdjustMatrix[2]) < 0.01 && - FXSYS_fabs(pPSFont->m_Glyphs[j].m_AdjustMatrix[3] - charpos.m_AdjustMatrix[3]) < 0.01))) { - ps_fontnum = i; - ps_glyphindex = j; - return; - } - } - } - if (m_PSFontList.GetSize() == 0 || m_PSFontList[m_PSFontList.GetSize() - 1]->m_nGlyphs == 256) { - CPSFont* pPSFont = new CPSFont; - pPSFont->m_nGlyphs = 0; - m_PSFontList.Add(pPSFont); - CFX_ByteTextBuf buf; - buf << FX_BSTRC("8 dict begin/FontType 3 def/FontMatrix[1 0 0 1 0 0]def\n" - "/FontBBox[0 0 0 0]def/Encoding 256 array def 0 1 255{Encoding exch/.notdef put}for\n" - "/CharProcs 1 dict def CharProcs begin/.notdef {} def end\n" - "/BuildGlyph{1 0 -10 -10 10 10 setcachedevice exch/CharProcs get exch 2 copy known not{pop/.notdef}if get exec}bind def\n" - "/BuildChar{1 index/Encoding get exch get 1 index/BuildGlyph get exec}bind def\n" - "currentdict end\n"); - buf << FX_BSTRC("/X") << m_PSFontList.GetSize() - 1 << FX_BSTRC(" exch definefont pop\n"); - m_pOutput->OutputPS((const FX_CHAR*)buf.GetBuffer(), buf.GetSize()); - buf.Clear(); - } - ps_fontnum = m_PSFontList.GetSize() - 1; - CPSFont* pPSFont = m_PSFontList[ps_fontnum]; - ps_glyphindex = pPSFont->m_nGlyphs; - pPSFont->m_Glyphs[ps_glyphindex].m_GlyphIndex = charpos.m_GlyphIndex; - pPSFont->m_Glyphs[ps_glyphindex].m_pFont = pFont; - pPSFont->m_Glyphs[ps_glyphindex].m_bGlyphAdjust = charpos.m_bGlyphAdjust; - if (charpos.m_bGlyphAdjust) { - pPSFont->m_Glyphs[ps_glyphindex].m_AdjustMatrix[0] = charpos.m_AdjustMatrix[0]; - pPSFont->m_Glyphs[ps_glyphindex].m_AdjustMatrix[1] = charpos.m_AdjustMatrix[1]; - pPSFont->m_Glyphs[ps_glyphindex].m_AdjustMatrix[2] = charpos.m_AdjustMatrix[2]; - pPSFont->m_Glyphs[ps_glyphindex].m_AdjustMatrix[3] = charpos.m_AdjustMatrix[3]; - } - pPSFont->m_nGlyphs ++; - CFX_AffineMatrix matrix; - if (charpos.m_bGlyphAdjust) - matrix.Set(charpos.m_AdjustMatrix[0], charpos.m_AdjustMatrix[1], - charpos.m_AdjustMatrix[2], charpos.m_AdjustMatrix[3], 0, 0); - matrix.Concat(1.0f, 0, 0, 1.0f, 0, 0); - const CFX_PathData* pPathData = pFaceCache->LoadGlyphPath(pFont, charpos.m_GlyphIndex, charpos.m_FontCharWidth); - if (pPathData == NULL) { - return; - } - CFX_PathData TransformedPath(*pPathData); - if (charpos.m_bGlyphAdjust) { - TransformedPath.Transform(&matrix); - } +void CFX_PSRenderer::SetColor(FX_DWORD color, + int alpha_flag, + void* pIccTransform) { + if (!CFX_GEModule::Get()->GetCodecModule() || + !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) { + pIccTransform = NULL; + } + FX_BOOL bCMYK = FALSE; + if (pIccTransform) { + ICodec_IccModule* pIccModule = + CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + color = FXGETFLAG_COLORTYPE(alpha_flag) ? FXCMYK_TODIB(color) + : FXARGB_TODIB(color); + uint8_t* pColor = (uint8_t*)&color; + pIccModule->TranslateScanline(pIccTransform, pColor, pColor, 1); + color = m_bCmykOutput ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); + bCMYK = m_bCmykOutput; + } else { + bCMYK = FXGETFLAG_COLORTYPE(alpha_flag); + } + if (bCMYK != m_bCmykOutput || !m_bColorSet || m_LastColor != color) { CFX_ByteTextBuf buf; - buf << FX_BSTRC("/X") << ps_fontnum << FX_BSTRC(" Ff/CharProcs get begin/") - << ps_glyphindex << FX_BSTRC("{"); - buf << FX_BSTRC("n "); - for (int p = 0; p < TransformedPath.GetPointCount(); p ++) { - FX_FLOAT x = TransformedPath.GetPointX(p), y = TransformedPath.GetPointY(p); - switch (TransformedPath.GetFlag(p) & FXPT_TYPE) { - case FXPT_MOVETO: { - buf << x << FX_BSTRC(" ") << y << FX_BSTRC(" m\n"); - break; - } - case FXPT_LINETO: { - buf << x << FX_BSTRC(" ") << y << FX_BSTRC(" l\n"); - break; - } - case FXPT_BEZIERTO: { - buf << x << FX_BSTRC(" ") << y << FX_BSTRC(" ") - << TransformedPath.GetPointX(p + 1) << FX_BSTRC(" ") - << TransformedPath.GetPointY(p + 1) << FX_BSTRC(" ") - << TransformedPath.GetPointX(p + 2) << FX_BSTRC(" ") - << TransformedPath.GetPointY(p + 2) << FX_BSTRC(" c\n"); - p += 2; - break; - } - } + if (bCMYK) { + buf << FXSYS_GetCValue(color) / 255.0 << FX_BSTRC(" ") + << FXSYS_GetMValue(color) / 255.0 << FX_BSTRC(" ") + << FXSYS_GetYValue(color) / 255.0 << FX_BSTRC(" ") + << FXSYS_GetKValue(color) / 255.0 << FX_BSTRC(" k\n"); + } else { + buf << FXARGB_R(color) / 255.0 << FX_BSTRC(" ") << FXARGB_G(color) / 255.0 + << FX_BSTRC(" ") << FXARGB_B(color) / 255.0 << FX_BSTRC(" rg\n"); + } + if (bCMYK == m_bCmykOutput) { + m_bColorSet = TRUE; + m_LastColor = color; } - buf << FX_BSTRC("f"); - buf << FX_BSTRC("}bind def end\n"); - buf << FX_BSTRC("/X") << ps_fontnum << FX_BSTRC(" Ff/Encoding get ") << ps_glyphindex - << FX_BSTRC("/") << ps_glyphindex << FX_BSTRC(" put\n"); m_pOutput->OutputPS((const FX_CHAR*)buf.GetBuffer(), buf.GetSize()); + } } -FX_BOOL CFX_PSRenderer::DrawText(int nChars, const FXTEXT_CHARPOS* pCharPos, CFX_Font* pFont, - CFX_FontCache* pCache, const CFX_AffineMatrix* pObject2Device, - FX_FLOAT font_size, FX_DWORD color, - int alpha_flag, void* pIccTransform) -{ - StartRendering(); - int alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(color); - if (alpha < 255) { - return FALSE; - } - if ((pObject2Device->a == 0 && pObject2Device->b == 0) || (pObject2Device->c == 0 && pObject2Device->d == 0)) { - return TRUE; - } - SetColor(color, alpha_flag, pIccTransform); - CFX_ByteTextBuf buf; - buf << FX_BSTRC("q[") << pObject2Device->a << FX_BSTRC(" ") << pObject2Device->b << FX_BSTRC(" ") - << pObject2Device->c << FX_BSTRC(" ") << pObject2Device->d; - buf << FX_BSTRC(" ") << pObject2Device->e << FX_BSTRC(" ") << pObject2Device->f << "]cm\n"; - if (pCache == NULL) { - pCache = CFX_GEModule::Get()->GetFontCache(); - } - CFX_FaceCache* pFaceCache = pCache->GetCachedFace(pFont); - FX_FONTCACHE_DEFINE(pCache, pFont); - int last_fontnum = -1; - for (int i = 0; i < nChars; i ++) { - int ps_fontnum, ps_glyphindex; - FindPSFontGlyph(pFaceCache, pFont, pCharPos[i], ps_fontnum, ps_glyphindex); - if (last_fontnum != ps_fontnum) { - buf << FX_BSTRC("/X") << ps_fontnum << FX_BSTRC(" Ff ") << font_size - << FX_BSTRC(" Fs Sf "); - last_fontnum = ps_fontnum; +void CFX_PSRenderer::FindPSFontGlyph(CFX_FaceCache* pFaceCache, + CFX_Font* pFont, + const FXTEXT_CHARPOS& charpos, + int& ps_fontnum, + int& ps_glyphindex) { + for (int i = 0; i < (int)m_PSFontList.GetSize(); i++) { + CPSFont* pPSFont = m_PSFontList[i]; + for (int j = 0; j < pPSFont->m_nGlyphs; j++) + if (pPSFont->m_Glyphs[j].m_pFont == pFont && + pPSFont->m_Glyphs[j].m_GlyphIndex == charpos.m_GlyphIndex) { + if ((!pPSFont->m_Glyphs[j].m_bGlyphAdjust && !charpos.m_bGlyphAdjust) || + (pPSFont->m_Glyphs[j].m_bGlyphAdjust && charpos.m_bGlyphAdjust && + (FXSYS_fabs(pPSFont->m_Glyphs[j].m_AdjustMatrix[0] - + charpos.m_AdjustMatrix[0]) < 0.01 && + FXSYS_fabs(pPSFont->m_Glyphs[j].m_AdjustMatrix[1] - + charpos.m_AdjustMatrix[1]) < 0.01 && + FXSYS_fabs(pPSFont->m_Glyphs[j].m_AdjustMatrix[2] - + charpos.m_AdjustMatrix[2]) < 0.01 && + FXSYS_fabs(pPSFont->m_Glyphs[j].m_AdjustMatrix[3] - + charpos.m_AdjustMatrix[3]) < 0.01))) { + ps_fontnum = i; + ps_glyphindex = j; + return; } - buf << pCharPos[i].m_OriginX << FX_BSTRC(" ") - << pCharPos[i].m_OriginY << FX_BSTRC(" m"); - CFX_ByteString hex; - hex.Format("<%02X>", ps_glyphindex); - buf << hex << FX_BSTRC("Tj\n"); - } - buf << FX_BSTRC("Q\n"); + } + } + if (m_PSFontList.GetSize() == 0 || + m_PSFontList[m_PSFontList.GetSize() - 1]->m_nGlyphs == 256) { + CPSFont* pPSFont = new CPSFont; + pPSFont->m_nGlyphs = 0; + m_PSFontList.Add(pPSFont); + CFX_ByteTextBuf buf; + buf << FX_BSTRC( + "8 dict begin/FontType 3 def/FontMatrix[1 0 0 1 0 0]def\n" + "/FontBBox[0 0 0 0]def/Encoding 256 array def 0 1 255{Encoding " + "exch/.notdef put}for\n" + "/CharProcs 1 dict def CharProcs begin/.notdef {} def end\n" + "/BuildGlyph{1 0 -10 -10 10 10 setcachedevice exch/CharProcs get exch " + "2 copy known not{pop/.notdef}if get exec}bind def\n" + "/BuildChar{1 index/Encoding get exch get 1 index/BuildGlyph get " + "exec}bind def\n" + "currentdict end\n"); + buf << FX_BSTRC("/X") << m_PSFontList.GetSize() - 1 + << FX_BSTRC(" exch definefont pop\n"); m_pOutput->OutputPS((const FX_CHAR*)buf.GetBuffer(), buf.GetSize()); + buf.Clear(); + } + ps_fontnum = m_PSFontList.GetSize() - 1; + CPSFont* pPSFont = m_PSFontList[ps_fontnum]; + ps_glyphindex = pPSFont->m_nGlyphs; + pPSFont->m_Glyphs[ps_glyphindex].m_GlyphIndex = charpos.m_GlyphIndex; + pPSFont->m_Glyphs[ps_glyphindex].m_pFont = pFont; + pPSFont->m_Glyphs[ps_glyphindex].m_bGlyphAdjust = charpos.m_bGlyphAdjust; + if (charpos.m_bGlyphAdjust) { + pPSFont->m_Glyphs[ps_glyphindex].m_AdjustMatrix[0] = + charpos.m_AdjustMatrix[0]; + pPSFont->m_Glyphs[ps_glyphindex].m_AdjustMatrix[1] = + charpos.m_AdjustMatrix[1]; + pPSFont->m_Glyphs[ps_glyphindex].m_AdjustMatrix[2] = + charpos.m_AdjustMatrix[2]; + pPSFont->m_Glyphs[ps_glyphindex].m_AdjustMatrix[3] = + charpos.m_AdjustMatrix[3]; + } + pPSFont->m_nGlyphs++; + CFX_AffineMatrix matrix; + if (charpos.m_bGlyphAdjust) + matrix.Set(charpos.m_AdjustMatrix[0], charpos.m_AdjustMatrix[1], + charpos.m_AdjustMatrix[2], charpos.m_AdjustMatrix[3], 0, 0); + matrix.Concat(1.0f, 0, 0, 1.0f, 0, 0); + const CFX_PathData* pPathData = pFaceCache->LoadGlyphPath( + pFont, charpos.m_GlyphIndex, charpos.m_FontCharWidth); + if (pPathData == NULL) { + return; + } + CFX_PathData TransformedPath(*pPathData); + if (charpos.m_bGlyphAdjust) { + TransformedPath.Transform(&matrix); + } + CFX_ByteTextBuf buf; + buf << FX_BSTRC("/X") << ps_fontnum << FX_BSTRC(" Ff/CharProcs get begin/") + << ps_glyphindex << FX_BSTRC("{"); + buf << FX_BSTRC("n "); + for (int p = 0; p < TransformedPath.GetPointCount(); p++) { + FX_FLOAT x = TransformedPath.GetPointX(p), y = TransformedPath.GetPointY(p); + switch (TransformedPath.GetFlag(p) & FXPT_TYPE) { + case FXPT_MOVETO: { + buf << x << FX_BSTRC(" ") << y << FX_BSTRC(" m\n"); + break; + } + case FXPT_LINETO: { + buf << x << FX_BSTRC(" ") << y << FX_BSTRC(" l\n"); + break; + } + case FXPT_BEZIERTO: { + buf << x << FX_BSTRC(" ") << y << FX_BSTRC(" ") + << TransformedPath.GetPointX(p + 1) << FX_BSTRC(" ") + << TransformedPath.GetPointY(p + 1) << FX_BSTRC(" ") + << TransformedPath.GetPointX(p + 2) << FX_BSTRC(" ") + << TransformedPath.GetPointY(p + 2) << FX_BSTRC(" c\n"); + p += 2; + break; + } + } + } + buf << FX_BSTRC("f"); + buf << FX_BSTRC("}bind def end\n"); + buf << FX_BSTRC("/X") << ps_fontnum << FX_BSTRC(" Ff/Encoding get ") + << ps_glyphindex << FX_BSTRC("/") << ps_glyphindex << FX_BSTRC(" put\n"); + m_pOutput->OutputPS((const FX_CHAR*)buf.GetBuffer(), buf.GetSize()); +} +FX_BOOL CFX_PSRenderer::DrawText(int nChars, + const FXTEXT_CHARPOS* pCharPos, + CFX_Font* pFont, + CFX_FontCache* pCache, + const CFX_AffineMatrix* pObject2Device, + FX_FLOAT font_size, + FX_DWORD color, + int alpha_flag, + void* pIccTransform) { + StartRendering(); + int alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_FILL(alpha_flag) + : FXARGB_A(color); + if (alpha < 255) { + return FALSE; + } + if ((pObject2Device->a == 0 && pObject2Device->b == 0) || + (pObject2Device->c == 0 && pObject2Device->d == 0)) { return TRUE; + } + SetColor(color, alpha_flag, pIccTransform); + CFX_ByteTextBuf buf; + buf << FX_BSTRC("q[") << pObject2Device->a << FX_BSTRC(" ") + << pObject2Device->b << FX_BSTRC(" ") << pObject2Device->c + << FX_BSTRC(" ") << pObject2Device->d; + buf << FX_BSTRC(" ") << pObject2Device->e << FX_BSTRC(" ") + << pObject2Device->f << "]cm\n"; + if (pCache == NULL) { + pCache = CFX_GEModule::Get()->GetFontCache(); + } + CFX_FaceCache* pFaceCache = pCache->GetCachedFace(pFont); + FX_FONTCACHE_DEFINE(pCache, pFont); + int last_fontnum = -1; + for (int i = 0; i < nChars; i++) { + int ps_fontnum, ps_glyphindex; + FindPSFontGlyph(pFaceCache, pFont, pCharPos[i], ps_fontnum, ps_glyphindex); + if (last_fontnum != ps_fontnum) { + buf << FX_BSTRC("/X") << ps_fontnum << FX_BSTRC(" Ff ") << font_size + << FX_BSTRC(" Fs Sf "); + last_fontnum = ps_fontnum; + } + buf << pCharPos[i].m_OriginX << FX_BSTRC(" ") << pCharPos[i].m_OriginY + << FX_BSTRC(" m"); + CFX_ByteString hex; + hex.Format("<%02X>", ps_glyphindex); + buf << hex << FX_BSTRC("Tj\n"); + } + buf << FX_BSTRC("Q\n"); + m_pOutput->OutputPS((const FX_CHAR*)buf.GetBuffer(), buf.GetSize()); + return TRUE; } -void CFX_PSRenderer::WritePSBinary(const uint8_t* data, int len) -{ - uint8_t* dest_buf; - FX_DWORD dest_size; - CCodec_ModuleMgr* pEncoders = CFX_GEModule::Get()->GetCodecModule(); - if (pEncoders && pEncoders->GetBasicModule()->A85Encode(data, len, dest_buf, dest_size)) { - m_pOutput->OutputPS((const FX_CHAR*)dest_buf, dest_size); - FX_Free(dest_buf); - } else { - m_pOutput->OutputPS((const FX_CHAR*)data, len); - } +void CFX_PSRenderer::WritePSBinary(const uint8_t* data, int len) { + uint8_t* dest_buf; + FX_DWORD dest_size; + CCodec_ModuleMgr* pEncoders = CFX_GEModule::Get()->GetCodecModule(); + if (pEncoders && + pEncoders->GetBasicModule()->A85Encode(data, len, dest_buf, dest_size)) { + m_pOutput->OutputPS((const FX_CHAR*)dest_buf, dest_size); + FX_Free(dest_buf); + } else { + m_pOutput->OutputPS((const FX_CHAR*)data, len); + } } diff --git a/core/src/fxge/ge/fx_ge_text.cpp b/core/src/fxge/ge/fx_ge_text.cpp index 59a4cfb37d..7a84330ac0 100644 --- a/core/src/fxge/ge/fx_ge_text.cpp +++ b/core/src/fxge/ge/fx_ge_text.cpp @@ -10,1709 +10,1969 @@ #include "text_int.h" #undef FX_GAMMA #undef FX_GAMMA_INVERSE -#define FX_GAMMA(value) (value) -#define FX_GAMMA_INVERSE(value) (value) +#define FX_GAMMA(value) (value) +#define FX_GAMMA_INVERSE(value) (value) namespace { void ResetTransform(FT_Face face) { - FXFT_Matrix matrix; - matrix.xx = 0x10000L; - matrix.xy = 0; - matrix.yx = 0; - matrix.yy = 0x10000L; - FXFT_Set_Transform(face, &matrix, 0); + FXFT_Matrix matrix; + matrix.xx = 0x10000L; + matrix.xy = 0; + matrix.yx = 0; + matrix.yy = 0x10000L; + FXFT_Set_Transform(face, &matrix, 0); } // Sets the given transform on the font, and resets it to the identity when it // goes out of scope. -class ScopedFontTransform -{ -public: - ScopedFontTransform(FT_Face face, FXFT_Matrix* matrix) : m_Face(face) { - FXFT_Set_Transform(m_Face, matrix, 0); - } +class ScopedFontTransform { + public: + ScopedFontTransform(FT_Face face, FXFT_Matrix* matrix) : m_Face(face) { + FXFT_Set_Transform(m_Face, matrix, 0); + } - ~ScopedFontTransform() { - ResetTransform(m_Face); - } + ~ScopedFontTransform() { ResetTransform(m_Face); } -private: - FT_Face m_Face; + private: + FT_Face m_Face; }; - } -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 == NULL) { - 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; +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 == NULL) { + 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) { - 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; - 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; - } +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) { + 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; + 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; + } } static 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, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 71, 72, - 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, - 121, 122, 123, 124, 125, 126, 127, 128, 129, 129, 130, 131, 132, 133, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, - 152, 153, 154, 155, 156, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 174, 175, 176, 177, 178, 179, 180, 181, - 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 193, 194, 195, 196, - 197, 198, 199, 200, 201, 202, 203, 204, 204, 205, 206, 207, 208, 209, 210, 211, - 212, 213, 214, 215, 216, 217, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 227, 228, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 239, 240, - 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 250, 251, 252, 253, 254, 255, + 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, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, + 186, 187, 188, 189, 190, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, + 214, 215, 216, 217, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, + 228, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 239, 240, + 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, FX_DWORD color, int alpha_flag, void* pIccTransform) -{ - if (pIccTransform == NULL && !FXGETFLAG_COLORTYPE(alpha_flag)) { - argb = color; - return; - } - if (!CFX_GEModule::Get()->GetCodecModule() || !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) { - pIccTransform = NULL; - } - uint8_t bgra[4]; - if (pIccTransform) { - ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - color = FXGETFLAG_COLORTYPE(alpha_flag) ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); - pIccModule->TranslateScanline(pIccTransform, bgra, (const uint8_t*)&color, 1); - bgra[3] = FXGETFLAG_COLORTYPE(alpha_flag) ? - (alpha_flag >> 24) ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXGETFLAG_ALPHA_STROKE(alpha_flag) : - FXARGB_A(color); - argb = FXARGB_MAKE(bgra[3], bgra[2], bgra[1], bgra[0]); - return; - } - AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), - FXSYS_GetYValue(color), FXSYS_GetKValue(color), - bgra[2], bgra[1], bgra[0]); - bgra[3] = (alpha_flag >> 24) ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXGETFLAG_ALPHA_STROKE(alpha_flag); + src_alpha = g_TextGammaAdjust[(uint8_t)src_alpha]; +void _Color2Argb(FX_ARGB& argb, + FX_DWORD color, + int alpha_flag, + void* pIccTransform) { + if (pIccTransform == NULL && !FXGETFLAG_COLORTYPE(alpha_flag)) { + argb = color; + return; + } + if (!CFX_GEModule::Get()->GetCodecModule() || + !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) { + pIccTransform = NULL; + } + uint8_t bgra[4]; + if (pIccTransform) { + ICodec_IccModule* pIccModule = + CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + color = FXGETFLAG_COLORTYPE(alpha_flag) ? FXCMYK_TODIB(color) + : FXARGB_TODIB(color); + pIccModule->TranslateScanline(pIccTransform, bgra, (const uint8_t*)&color, + 1); + bgra[3] = FXGETFLAG_COLORTYPE(alpha_flag) + ? (alpha_flag >> 24) ? FXGETFLAG_ALPHA_FILL(alpha_flag) + : FXGETFLAG_ALPHA_STROKE(alpha_flag) + : FXARGB_A(color); argb = FXARGB_MAKE(bgra[3], bgra[2], bgra[1], bgra[0]); + return; + } + AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), + FXSYS_GetYValue(color), FXSYS_GetKValue(color), bgra[2], + bgra[1], bgra[0]); + bgra[3] = (alpha_flag >> 24) ? FXGETFLAG_ALPHA_FILL(alpha_flag) + : FXGETFLAG_ALPHA_STROKE(alpha_flag); + argb = FXARGB_MAKE(bgra[3], bgra[2], bgra[1], bgra[0]); } -FX_BOOL CFX_RenderDevice::DrawNormalText(int nChars, const FXTEXT_CHARPOS* pCharPos, - CFX_Font* pFont, CFX_FontCache* pCache, - FX_FLOAT font_size, const CFX_AffineMatrix* pText2Device, - FX_DWORD fill_color, FX_DWORD text_flags, - int alpha_flag, void* pIccTransform) -{ - int nativetext_flags = text_flags; - if (m_DeviceClass != FXDC_DISPLAY) { - if (!(text_flags & FXTEXT_PRINTGRAPHICTEXT)) { -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - if (!(text_flags & FXFONT_CIDFONT) && pFont->GetPsName().Find(CFX_WideString::FromLocal("+ZJHL")) == -1) +FX_BOOL CFX_RenderDevice::DrawNormalText(int nChars, + const FXTEXT_CHARPOS* pCharPos, + CFX_Font* pFont, + CFX_FontCache* pCache, + FX_FLOAT font_size, + const CFX_AffineMatrix* pText2Device, + FX_DWORD fill_color, + FX_DWORD text_flags, + int alpha_flag, + void* pIccTransform) { + int nativetext_flags = text_flags; + if (m_DeviceClass != FXDC_DISPLAY) { + if (!(text_flags & FXTEXT_PRINTGRAPHICTEXT)) { +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + if (!(text_flags & FXFONT_CIDFONT) && + pFont->GetPsName().Find(CFX_WideString::FromLocal("+ZJHL")) == -1) #ifdef FOXIT_CHROME_BUILD - if (pFont->GetPsName() != CFX_WideString::FromLocal("CNAAJI+cmex10")) + if (pFont->GetPsName() != CFX_WideString::FromLocal("CNAAJI+cmex10")) #endif #endif - if (m_pDeviceDriver->DrawDeviceText(nChars, pCharPos, pFont, pCache, pText2Device, font_size, fill_color, alpha_flag, pIccTransform)) { - return TRUE; - } - } - int alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(fill_color); - if (alpha < 255) { - return FALSE; - } - } else if (!(text_flags & FXTEXT_NO_NATIVETEXT)) { -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - if (!(text_flags & FXFONT_CIDFONT)) + if (m_pDeviceDriver->DrawDeviceText( + nChars, pCharPos, pFont, pCache, pText2Device, font_size, + fill_color, alpha_flag, pIccTransform)) { + return TRUE; + } + } + int alpha = FXGETFLAG_COLORTYPE(alpha_flag) + ? FXGETFLAG_ALPHA_FILL(alpha_flag) + : FXARGB_A(fill_color); + if (alpha < 255) { + return FALSE; + } + } else if (!(text_flags & FXTEXT_NO_NATIVETEXT)) { +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + if (!(text_flags & FXFONT_CIDFONT)) #ifdef FOXIT_CHROME_BUILD - if (pFont->GetPsName() != CFX_WideString::FromLocal("CNAAJI+cmex10")) + if (pFont->GetPsName() != CFX_WideString::FromLocal("CNAAJI+cmex10")) #endif #endif - if (m_pDeviceDriver->DrawDeviceText(nChars, pCharPos, pFont, pCache, pText2Device, font_size, fill_color, alpha_flag, pIccTransform)) { - return TRUE; - } - } - CFX_AffineMatrix char2device, deviceCtm, text2Device; - if (pText2Device) { - char2device = *pText2Device; - text2Device = *pText2Device; - } - char2device.Scale(font_size, -font_size); - if (FXSYS_fabs(char2device.a) + FXSYS_fabs(char2device.b) > 50 * 1.0f || - ((m_DeviceClass == FXDC_PRINTER && !m_pDeviceDriver->IsPSPrintDriver()) - && !(text_flags & FXTEXT_PRINTIMAGETEXT))) { - if (pFont->GetFace() != NULL || (pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_GLYPHPATH)) { - int nPathFlags = (text_flags & FXTEXT_NOSMOOTH) == 0 ? 0 : FXFILL_NOPATHSMOOTH; - return DrawTextPath(nChars, pCharPos, pFont, pCache, font_size, pText2Device, NULL, NULL, fill_color, 0, NULL, nPathFlags, alpha_flag, pIccTransform); - } - } - int anti_alias = FXFT_RENDER_MODE_MONO; - FX_BOOL bNormal = FALSE; - if ((text_flags & FXTEXT_NOSMOOTH) == 0) { - if (m_DeviceClass == FXDC_DISPLAY && m_bpp > 1) { - FX_BOOL bClearType; - if (pFont->GetFace() == NULL && !(pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_CLEARTYPE)) { - bClearType = FALSE; - } else { - bClearType = text_flags & FXTEXT_CLEARTYPE; - } - if ((m_RenderCaps & (FXRC_ALPHA_OUTPUT | FXRC_CMYK_OUTPUT))) { - anti_alias = FXFT_RENDER_MODE_LCD; - 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; - } - } + if (m_pDeviceDriver->DrawDeviceText(nChars, pCharPos, pFont, pCache, + pText2Device, font_size, fill_color, + alpha_flag, pIccTransform)) { + return TRUE; } - } - if (pCache == NULL) { - 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; - CFX_AffineMatrix matrixCTM = GetCTM(); - FX_FLOAT scale_x = FXSYS_fabs(matrixCTM.a); - FX_FLOAT scale_y = FXSYS_fabs(matrixCTM.d); - 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]; - glyph.m_fOriginX = charpos.m_OriginX; - glyph.m_fOriginY = charpos.m_OriginY; - text2Device.Transform(glyph.m_fOriginX, glyph.m_fOriginY); - if (anti_alias < FXFT_RENDER_MODE_LCD) { - glyph.m_OriginX = FXSYS_round(glyph.m_fOriginX); + } + CFX_AffineMatrix char2device, deviceCtm, text2Device; + if (pText2Device) { + char2device = *pText2Device; + text2Device = *pText2Device; + } + char2device.Scale(font_size, -font_size); + if (FXSYS_fabs(char2device.a) + FXSYS_fabs(char2device.b) > 50 * 1.0f || + ((m_DeviceClass == FXDC_PRINTER && !m_pDeviceDriver->IsPSPrintDriver()) && + !(text_flags & FXTEXT_PRINTIMAGETEXT))) { + if (pFont->GetFace() != NULL || + (pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_GLYPHPATH)) { + int nPathFlags = + (text_flags & FXTEXT_NOSMOOTH) == 0 ? 0 : FXFILL_NOPATHSMOOTH; + return DrawTextPath(nChars, pCharPos, pFont, pCache, font_size, + pText2Device, NULL, NULL, fill_color, 0, NULL, + nPathFlags, alpha_flag, pIccTransform); + } + } + int anti_alias = FXFT_RENDER_MODE_MONO; + FX_BOOL bNormal = FALSE; + if ((text_flags & FXTEXT_NOSMOOTH) == 0) { + if (m_DeviceClass == FXDC_DISPLAY && m_bpp > 1) { + FX_BOOL bClearType; + if (pFont->GetFace() == NULL && + !(pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_CLEARTYPE)) { + bClearType = FALSE; + } else { + bClearType = text_flags & FXTEXT_CLEARTYPE; + } + if ((m_RenderCaps & (FXRC_ALPHA_OUTPUT | FXRC_CMYK_OUTPUT))) { + anti_alias = FXFT_RENDER_MODE_LCD; + 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 { - glyph.m_OriginX = (int)FXSYS_floor(glyph.m_fOriginX); + anti_alias = FXFT_RENDER_MODE_LCD; } - glyph.m_OriginY = FXSYS_round(glyph.m_fOriginY); - if (charpos.m_bGlyphAdjust) { - CFX_AffineMatrix new_matrix(charpos.m_AdjustMatrix[0], charpos.m_AdjustMatrix[1], - charpos.m_AdjustMatrix[2], charpos.m_AdjustMatrix[3], 0, 0); - new_matrix.Concat(deviceCtm); - glyph.m_pGlyph = pFaceCache->LoadGlyphBitmap(pFont, charpos.m_GlyphIndex, charpos.m_bFontStyle, &new_matrix, - charpos.m_FontCharWidth, anti_alias, nativetext_flags); - } else - glyph.m_pGlyph = pFaceCache->LoadGlyphBitmap(pFont, charpos.m_GlyphIndex, charpos.m_bFontStyle, &deviceCtm, - 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 (scale_x > 1 && scale_y > 1) { - bmp_rect1.left--; - bmp_rect1.top --; - bmp_rect1.right ++; - bmp_rect1.bottom ++; + } + } + } + if (pCache == NULL) { + 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; + CFX_AffineMatrix matrixCTM = GetCTM(); + FX_FLOAT scale_x = FXSYS_fabs(matrixCTM.a); + FX_FLOAT scale_y = FXSYS_fabs(matrixCTM.d); + 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]; + glyph.m_fOriginX = charpos.m_OriginX; + glyph.m_fOriginY = charpos.m_OriginY; + text2Device.Transform(glyph.m_fOriginX, glyph.m_fOriginY); + if (anti_alias < FXFT_RENDER_MODE_LCD) { + glyph.m_OriginX = FXSYS_round(glyph.m_fOriginX); + } else { + glyph.m_OriginX = (int)FXSYS_floor(glyph.m_fOriginX); + } + glyph.m_OriginY = FXSYS_round(glyph.m_fOriginY); + if (charpos.m_bGlyphAdjust) { + CFX_AffineMatrix new_matrix( + charpos.m_AdjustMatrix[0], charpos.m_AdjustMatrix[1], + charpos.m_AdjustMatrix[2], charpos.m_AdjustMatrix[3], 0, 0); + new_matrix.Concat(deviceCtm); + glyph.m_pGlyph = pFaceCache->LoadGlyphBitmap( + pFont, charpos.m_GlyphIndex, charpos.m_bFontStyle, &new_matrix, + charpos.m_FontCharWidth, anti_alias, nativetext_flags); + } else + glyph.m_pGlyph = pFaceCache->LoadGlyphBitmap( + pFont, charpos.m_GlyphIndex, charpos.m_bFontStyle, &deviceCtm, + 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 (scale_x > 1 && scale_y > 1) { + bmp_rect1.left--; + bmp_rect1.top--; + bmp_rect1.right++; + bmp_rect1.bottom++; + } + FX_RECT bmp_rect(FXSYS_round((FX_FLOAT)(bmp_rect1.left) / scale_x), + FXSYS_round((FX_FLOAT)(bmp_rect1.top) / scale_y), + 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); + 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); + return FALSE; + } + bitmap.Clear(0); + for (iChar = 0; iChar < nChars; iChar++) { + FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[iChar]; + if (glyph.m_pGlyph == NULL) { + 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_RECT bmp_rect(FXSYS_round((FX_FLOAT)(bmp_rect1.left) / scale_x), FXSYS_round((FX_FLOAT)(bmp_rect1.top) / scale_y), - 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); + 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); + return FALSE; + } + } else { + if (!CreateCompatibleBitmap(&bitmap, pixel_width, pixel_height)) { + FX_Free(pGlyphAndPos); + return FALSE; + } + } + if (!bitmap.HasAlpha() && !bitmap.IsAlphaMask()) { + bitmap.Clear(0xFFFFFFFF); + if (!GetDIBits(&bitmap, bmp_rect.left, bmp_rect.top)) { + FX_Free(pGlyphAndPos); + 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, r, g, b; + if (anti_alias == FXFT_RENDER_MODE_LCD) { + _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 == NULL) { + 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; + int ncols = pGlyph->GetWidth(); + 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); - 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); - return FALSE; + return FALSE; + } + continue; + } + FX_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) { + 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; } - bitmap.Clear(0); - for (iChar = 0; iChar < nChars; iChar ++) { - FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[iChar]; - if (glyph.m_pGlyph == NULL) { - 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; } - 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); - return FALSE; - } - } else { - if (!CreateCompatibleBitmap(&bitmap, pixel_width, pixel_height)) { - FX_Free(pGlyphAndPos); - return FALSE; - } - } - if (!bitmap.HasAlpha() && !bitmap.IsAlphaMask()) { - bitmap.Clear(0xFFFFFFFF); - if (!GetDIBits(&bitmap, bmp_rect.left, bmp_rect.top)) { - FX_Free(pGlyphAndPos); - 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, r, g, b; - if (anti_alias == FXFT_RENDER_MODE_LCD) { - _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 == NULL) { - 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; - int ncols = pGlyph->GetWidth(); - 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); - return FALSE; + } 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)); } - continue; - } - FX_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) { - 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; + 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; } - 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; - } - } + 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 { - 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; - } - } + 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; } - } else { - for (int row = 0; row < nrows; row ++) { - int dest_row = row + top; - if (dest_row < 0 || dest_row >= bitmap.GetHeight()) { - continue; + 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; } - 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; - } - } + 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 { - 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; - } - } + 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; } + } } - } - if (bitmap.IsAlphaMask()) { - SetBitMask(&bitmap, bmp_rect.left, bmp_rect.top, fill_color, alpha_flag, pIccTransform); + } } 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, CFX_FontCache* pCache, - FX_FLOAT font_size, const CFX_AffineMatrix* pText2User, - const CFX_AffineMatrix* pUser2Device, const CFX_GraphStateData* pGraphState, - FX_DWORD fill_color, FX_ARGB stroke_color, CFX_PathData* pClippingPath, int nFlag, - int alpha_flag, void* pIccTransform, int blend_type) -{ - if (pCache == NULL) { - pCache = CFX_GEModule::Get()->GetFontCache(); - } - CFX_FaceCache* pFaceCache = pCache->GetCachedFace(pFont); - FX_FONTCACHE_DEFINE(pCache, pFont); - for (int iChar = 0; iChar < nChars; iChar ++) { - const FXTEXT_CHARPOS& charpos = pCharPos[iChar]; - CFX_AffineMatrix matrix; - if (charpos.m_bGlyphAdjust) - matrix.Set(charpos.m_AdjustMatrix[0], charpos.m_AdjustMatrix[1], - charpos.m_AdjustMatrix[2], charpos.m_AdjustMatrix[3], 0, 0); - matrix.Concat(font_size, 0, 0, font_size, charpos.m_OriginX, charpos.m_OriginY); - const CFX_PathData* pPath = pFaceCache->LoadGlyphPath(pFont, charpos.m_GlyphIndex, charpos.m_FontCharWidth); - if (pPath == NULL) { - continue; + for (int row = 0; row < nrows; row++) { + int dest_row = row + top; + if (dest_row < 0 || dest_row >= bitmap.GetHeight()) { + continue; } - matrix.Concat(*pText2User); - CFX_PathData TransformedPath(*pPath); - TransformedPath.Transform(&matrix); - FX_BOOL bHasAlpha = FXGETFLAG_COLORTYPE(alpha_flag) ? - (FXGETFLAG_ALPHA_FILL(alpha_flag) || FXGETFLAG_ALPHA_STROKE(alpha_flag)) : - (fill_color || stroke_color); - if (bHasAlpha) { - int fill_mode = nFlag; - if (FXGETFLAG_COLORTYPE(alpha_flag)) { - if (FXGETFLAG_ALPHA_FILL(alpha_flag)) { - fill_mode |= FXFILL_WINDING; + 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 (fill_color) { - fill_mode |= FXFILL_WINDING; + 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; } - fill_mode |= FX_FILL_TEXT_MODE; - if (!DrawPath(&TransformedPath, pUser2Device, pGraphState, fill_color, stroke_color, fill_mode, alpha_flag, pIccTransform, blend_type)) { - return FALSE; + } 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; + } + } } - if (pClippingPath) { - pClippingPath->Append(&TransformedPath, pUser2Device); + } + } + } + if (bitmap.IsAlphaMask()) { + SetBitMask(&bitmap, bmp_rect.left, bmp_rect.top, fill_color, alpha_flag, + pIccTransform); + } 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, + CFX_FontCache* pCache, + FX_FLOAT font_size, + const CFX_AffineMatrix* pText2User, + const CFX_AffineMatrix* pUser2Device, + const CFX_GraphStateData* pGraphState, + FX_DWORD fill_color, + FX_ARGB stroke_color, + CFX_PathData* pClippingPath, + int nFlag, + int alpha_flag, + void* pIccTransform, + int blend_type) { + if (pCache == NULL) { + pCache = CFX_GEModule::Get()->GetFontCache(); + } + CFX_FaceCache* pFaceCache = pCache->GetCachedFace(pFont); + FX_FONTCACHE_DEFINE(pCache, pFont); + for (int iChar = 0; iChar < nChars; iChar++) { + const FXTEXT_CHARPOS& charpos = pCharPos[iChar]; + CFX_AffineMatrix matrix; + if (charpos.m_bGlyphAdjust) + matrix.Set(charpos.m_AdjustMatrix[0], charpos.m_AdjustMatrix[1], + charpos.m_AdjustMatrix[2], charpos.m_AdjustMatrix[3], 0, 0); + matrix.Concat(font_size, 0, 0, font_size, charpos.m_OriginX, + charpos.m_OriginY); + const CFX_PathData* pPath = pFaceCache->LoadGlyphPath( + pFont, charpos.m_GlyphIndex, charpos.m_FontCharWidth); + if (pPath == NULL) { + continue; + } + matrix.Concat(*pText2User); + CFX_PathData TransformedPath(*pPath); + TransformedPath.Transform(&matrix); + FX_BOOL bHasAlpha = FXGETFLAG_COLORTYPE(alpha_flag) + ? (FXGETFLAG_ALPHA_FILL(alpha_flag) || + FXGETFLAG_ALPHA_STROKE(alpha_flag)) + : (fill_color || stroke_color); + if (bHasAlpha) { + int fill_mode = nFlag; + if (FXGETFLAG_COLORTYPE(alpha_flag)) { + if (FXGETFLAG_ALPHA_FILL(alpha_flag)) { + fill_mode |= FXFILL_WINDING; } + } else { + if (fill_color) { + fill_mode |= FXFILL_WINDING; + } + } + fill_mode |= FX_FILL_TEXT_MODE; + if (!DrawPath(&TransformedPath, pUser2Device, pGraphState, fill_color, + stroke_color, fill_mode, alpha_flag, pIccTransform, + blend_type)) { + return FALSE; + } } - return TRUE; + if (pClippingPath) { + pClippingPath->Append(&TransformedPath, pUser2Device); + } + } + return TRUE; } -CFX_FontCache::~CFX_FontCache() -{ - FreeCache(TRUE); +CFX_FontCache::~CFX_FontCache() { + FreeCache(TRUE); } -CFX_FaceCache* CFX_FontCache::GetCachedFace(CFX_Font* pFont) -{ - FXFT_Face internal_face = pFont->GetFace(); - const FX_BOOL bExternal = internal_face == nullptr; - FXFT_Face face = bExternal ? - (FXFT_Face)pFont->GetSubstFont()->m_ExtHandle : internal_face; - CFX_FTCacheMap& map = bExternal ? m_ExtFaceMap : m_FTFaceMap; - auto it = map.find(face); - if (it != map.end()) { - CFX_CountedFaceCache* counted_face_cache = it->second; - counted_face_cache->m_nCount++; - return counted_face_cache->m_Obj; - } +CFX_FaceCache* CFX_FontCache::GetCachedFace(CFX_Font* pFont) { + FXFT_Face internal_face = pFont->GetFace(); + const FX_BOOL bExternal = internal_face == nullptr; + FXFT_Face face = + bExternal ? (FXFT_Face)pFont->GetSubstFont()->m_ExtHandle : internal_face; + CFX_FTCacheMap& map = bExternal ? m_ExtFaceMap : m_FTFaceMap; + auto it = map.find(face); + if (it != map.end()) { + CFX_CountedFaceCache* counted_face_cache = it->second; + counted_face_cache->m_nCount++; + return counted_face_cache->m_Obj; + } - CFX_FaceCache* face_cache = new CFX_FaceCache(bExternal ? nullptr : face); - CFX_CountedFaceCache* counted_face_cache = new CFX_CountedFaceCache; - counted_face_cache->m_nCount = 2; - counted_face_cache->m_Obj = face_cache; - map[face] = counted_face_cache; - return face_cache; + CFX_FaceCache* face_cache = new CFX_FaceCache(bExternal ? nullptr : face); + CFX_CountedFaceCache* counted_face_cache = new CFX_CountedFaceCache; + counted_face_cache->m_nCount = 2; + counted_face_cache->m_Obj = face_cache; + map[face] = counted_face_cache; + return face_cache; } -void CFX_FontCache::ReleaseCachedFace(CFX_Font* pFont) -{ - FXFT_Face internal_face = pFont->GetFace(); - const FX_BOOL bExternal = internal_face == nullptr; - FXFT_Face face = bExternal ? - (FXFT_Face)pFont->GetSubstFont()->m_ExtHandle : internal_face; - CFX_FTCacheMap& map = bExternal ? m_ExtFaceMap : m_FTFaceMap; +void CFX_FontCache::ReleaseCachedFace(CFX_Font* pFont) { + FXFT_Face internal_face = pFont->GetFace(); + const FX_BOOL bExternal = internal_face == nullptr; + FXFT_Face face = + bExternal ? (FXFT_Face)pFont->GetSubstFont()->m_ExtHandle : internal_face; + CFX_FTCacheMap& map = bExternal ? m_ExtFaceMap : m_FTFaceMap; - auto it = map.find(face); - if (it == map.end()) - return; + auto it = map.find(face); + if (it == map.end()) + return; - CFX_CountedFaceCache* counted_face_cache = it->second; - if (counted_face_cache->m_nCount > 1) { - counted_face_cache->m_nCount--; - } + CFX_CountedFaceCache* counted_face_cache = it->second; + if (counted_face_cache->m_nCount > 1) { + counted_face_cache->m_nCount--; + } } -void CFX_FontCache::FreeCache(FX_BOOL bRelease) -{ - for (auto it = m_FTFaceMap.begin(); it != m_FTFaceMap.end();) { - auto curr_it = it++; - CFX_CountedFaceCache* cache = curr_it->second; - if (bRelease || cache->m_nCount < 2) { - delete cache->m_Obj; - delete cache; - m_FTFaceMap.erase(curr_it); - } - } +void CFX_FontCache::FreeCache(FX_BOOL bRelease) { + for (auto it = m_FTFaceMap.begin(); it != m_FTFaceMap.end();) { + auto curr_it = it++; + CFX_CountedFaceCache* cache = curr_it->second; + if (bRelease || cache->m_nCount < 2) { + delete cache->m_Obj; + delete cache; + m_FTFaceMap.erase(curr_it); + } + } - for (auto it = m_ExtFaceMap.begin(); it != m_ExtFaceMap.end();) { - auto curr_it = it++; - CFX_CountedFaceCache* cache = curr_it->second; - if (bRelease || cache->m_nCount < 2) { - delete cache->m_Obj; - delete cache; - m_ExtFaceMap.erase(curr_it); - } - } + for (auto it = m_ExtFaceMap.begin(); it != m_ExtFaceMap.end();) { + auto curr_it = it++; + CFX_CountedFaceCache* cache = curr_it->second; + if (bRelease || cache->m_nCount < 2) { + delete cache->m_Obj; + delete cache; + m_ExtFaceMap.erase(curr_it); + } + } } -CFX_FaceCache::CFX_FaceCache(FXFT_Face face) -{ - m_Face = face; -} -CFX_FaceCache::~CFX_FaceCache() -{ - FX_POSITION pos = m_SizeMap.GetStartPosition(); - CFX_ByteString Key; - CFX_SizeGlyphCache* pSizeCache = NULL; - while(pos) { - m_SizeMap.GetNextAssoc( pos, Key, (void*&)pSizeCache); - delete pSizeCache; - } - m_SizeMap.RemoveAll(); - pos = m_PathMap.GetStartPosition(); - void* key1; - CFX_PathData* pPath; - while (pos) { - m_PathMap.GetNextAssoc(pos, key1, (void*&)pPath); - delete pPath; - } - m_PathMap.RemoveAll(); +CFX_FaceCache::CFX_FaceCache(FXFT_Face face) { + m_Face = face; } -#if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_ -void CFX_FaceCache::InitPlatform() -{ +CFX_FaceCache::~CFX_FaceCache() { + FX_POSITION pos = m_SizeMap.GetStartPosition(); + CFX_ByteString Key; + CFX_SizeGlyphCache* pSizeCache = NULL; + while (pos) { + m_SizeMap.GetNextAssoc(pos, Key, (void*&)pSizeCache); + delete pSizeCache; + } + m_SizeMap.RemoveAll(); + pos = m_PathMap.GetStartPosition(); + void* key1; + CFX_PathData* pPath; + while (pos) { + m_PathMap.GetNextAssoc(pos, key1, (void*&)pPath); + delete pPath; + } + m_PathMap.RemoveAll(); } +#if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_ +void CFX_FaceCache::InitPlatform() {} #endif -CFX_GlyphBitmap* CFX_FaceCache::LookUpGlyphBitmap(CFX_Font* pFont, const CFX_AffineMatrix* pMatrix, - CFX_ByteStringC& FaceGlyphsKey, FX_DWORD glyph_index, FX_BOOL bFontStyle, - int dest_width, int anti_alias) -{ - CFX_SizeGlyphCache* pSizeCache = NULL; - if (!m_SizeMap.Lookup(FaceGlyphsKey, (void*&)pSizeCache)) { - pSizeCache = new CFX_SizeGlyphCache; - m_SizeMap.SetAt(FaceGlyphsKey, pSizeCache); - } - CFX_GlyphBitmap* pGlyphBitmap = NULL; - if (pSizeCache->m_GlyphMap.Lookup((void*)(uintptr_t)glyph_index, (void*&)pGlyphBitmap)) { - return pGlyphBitmap; - } - pGlyphBitmap = RenderGlyph(pFont, glyph_index, bFontStyle, pMatrix, dest_width, anti_alias); - if (pGlyphBitmap == NULL) { - return NULL; - } - pSizeCache->m_GlyphMap.SetAt((void*)(uintptr_t)glyph_index, pGlyphBitmap); +CFX_GlyphBitmap* CFX_FaceCache::LookUpGlyphBitmap( + CFX_Font* pFont, + const CFX_AffineMatrix* pMatrix, + CFX_ByteStringC& FaceGlyphsKey, + FX_DWORD glyph_index, + FX_BOOL bFontStyle, + int dest_width, + int anti_alias) { + CFX_SizeGlyphCache* pSizeCache = NULL; + if (!m_SizeMap.Lookup(FaceGlyphsKey, (void*&)pSizeCache)) { + pSizeCache = new CFX_SizeGlyphCache; + m_SizeMap.SetAt(FaceGlyphsKey, pSizeCache); + } + CFX_GlyphBitmap* pGlyphBitmap = NULL; + if (pSizeCache->m_GlyphMap.Lookup((void*)(uintptr_t)glyph_index, + (void*&)pGlyphBitmap)) { return pGlyphBitmap; + } + pGlyphBitmap = RenderGlyph(pFont, glyph_index, bFontStyle, pMatrix, + dest_width, anti_alias); + if (pGlyphBitmap == NULL) { + return NULL; + } + pSizeCache->m_GlyphMap.SetAt((void*)(uintptr_t)glyph_index, pGlyphBitmap); + return pGlyphBitmap; } -const CFX_GlyphBitmap* CFX_FaceCache::LoadGlyphBitmap(CFX_Font* pFont, FX_DWORD glyph_index, FX_BOOL bFontStyle, const CFX_AffineMatrix* pMatrix, - int dest_width, int anti_alias, int& text_flags) -{ - if (glyph_index == (FX_DWORD) - 1) { - return NULL; - } - _CFX_UniqueKeyGen keygen; -#if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_ +const CFX_GlyphBitmap* CFX_FaceCache::LoadGlyphBitmap( + CFX_Font* pFont, + FX_DWORD glyph_index, + FX_BOOL bFontStyle, + const CFX_AffineMatrix* pMatrix, + int dest_width, + int anti_alias, + int& text_flags) { + if (glyph_index == (FX_DWORD)-1) { + return NULL; + } + _CFX_UniqueKeyGen keygen; +#if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_ + if (pFont->GetSubstFont()) + keygen.Generate(9, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000), + (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), + dest_width, anti_alias, pFont->GetSubstFont()->m_Weight, + pFont->GetSubstFont()->m_ItalicAngle, pFont->IsVertical()); + else + keygen.Generate(6, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000), + (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), + dest_width, anti_alias); +#else + if (text_flags & FXTEXT_NO_NATIVETEXT) { if (pFont->GetSubstFont()) - keygen.Generate(9, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000), - (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), dest_width, anti_alias, - pFont->GetSubstFont()->m_Weight, pFont->GetSubstFont()->m_ItalicAngle, pFont->IsVertical()); + keygen.Generate(9, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000), + (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), + dest_width, anti_alias, pFont->GetSubstFont()->m_Weight, + pFont->GetSubstFont()->m_ItalicAngle, + pFont->IsVertical()); else - keygen.Generate(6, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000), - (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), dest_width, anti_alias); -#else - if (text_flags & FXTEXT_NO_NATIVETEXT) { - if (pFont->GetSubstFont()) - keygen.Generate(9, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000), - (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), dest_width, anti_alias, - pFont->GetSubstFont()->m_Weight, pFont->GetSubstFont()->m_ItalicAngle, pFont->IsVertical()); - else - keygen.Generate(6, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000), - (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), dest_width, anti_alias); - } else { - if (pFont->GetSubstFont()) - keygen.Generate(10, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000), - (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), dest_width, anti_alias, - pFont->GetSubstFont()->m_Weight, pFont->GetSubstFont()->m_ItalicAngle, pFont->IsVertical(), 3); - else - keygen.Generate(7, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000), - (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), dest_width, anti_alias, 3); - } -#endif - CFX_ByteStringC FaceGlyphsKey(keygen.m_Key, keygen.m_KeyLen); -#if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_ - return LookUpGlyphBitmap(pFont, pMatrix, FaceGlyphsKey, glyph_index, bFontStyle, dest_width, anti_alias); -#else - if (text_flags & FXTEXT_NO_NATIVETEXT) { - return LookUpGlyphBitmap(pFont, pMatrix, FaceGlyphsKey, glyph_index, bFontStyle, dest_width, anti_alias); - } - CFX_GlyphBitmap* pGlyphBitmap; - CFX_SizeGlyphCache* pSizeCache = NULL; - if (m_SizeMap.Lookup(FaceGlyphsKey, (void*&)pSizeCache)) { - if (pSizeCache->m_GlyphMap.Lookup((void*)(uintptr_t)glyph_index, (void*&)pGlyphBitmap)) { - return pGlyphBitmap; - } - pGlyphBitmap = RenderGlyph_Nativetext(pFont, glyph_index, pMatrix, dest_width, anti_alias); - if (pGlyphBitmap) { - pSizeCache->m_GlyphMap.SetAt((void*)(uintptr_t)glyph_index, pGlyphBitmap); - return pGlyphBitmap; - } - } else { - pGlyphBitmap = RenderGlyph_Nativetext(pFont, glyph_index, pMatrix, dest_width, anti_alias); - if (pGlyphBitmap) { - pSizeCache = new CFX_SizeGlyphCache; - m_SizeMap.SetAt(FaceGlyphsKey, pSizeCache); - pSizeCache->m_GlyphMap.SetAt((void*)(uintptr_t)glyph_index, pGlyphBitmap); - return pGlyphBitmap; - } - } + keygen.Generate(6, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000), + (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), + dest_width, anti_alias); + } else { if (pFont->GetSubstFont()) - keygen.Generate(9, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000), - (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), dest_width, anti_alias, - pFont->GetSubstFont()->m_Weight, pFont->GetSubstFont()->m_ItalicAngle, pFont->IsVertical()); + keygen.Generate(10, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000), + (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), + dest_width, anti_alias, pFont->GetSubstFont()->m_Weight, + pFont->GetSubstFont()->m_ItalicAngle, pFont->IsVertical(), + 3); else - keygen.Generate(6, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000), - (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), dest_width, anti_alias); - CFX_ByteStringC FaceGlyphsKey2(keygen.m_Key, keygen.m_KeyLen); - text_flags |= FXTEXT_NO_NATIVETEXT; - return LookUpGlyphBitmap(pFont, pMatrix, FaceGlyphsKey2, glyph_index, bFontStyle, dest_width, anti_alias); + keygen.Generate(7, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000), + (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), + dest_width, anti_alias, 3); + } +#endif + CFX_ByteStringC FaceGlyphsKey(keygen.m_Key, keygen.m_KeyLen); +#if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_ + return LookUpGlyphBitmap(pFont, pMatrix, FaceGlyphsKey, glyph_index, + bFontStyle, dest_width, anti_alias); +#else + if (text_flags & FXTEXT_NO_NATIVETEXT) { + return LookUpGlyphBitmap(pFont, pMatrix, FaceGlyphsKey, glyph_index, + bFontStyle, dest_width, anti_alias); + } + CFX_GlyphBitmap* pGlyphBitmap; + CFX_SizeGlyphCache* pSizeCache = NULL; + if (m_SizeMap.Lookup(FaceGlyphsKey, (void*&)pSizeCache)) { + if (pSizeCache->m_GlyphMap.Lookup((void*)(uintptr_t)glyph_index, + (void*&)pGlyphBitmap)) { + return pGlyphBitmap; + } + pGlyphBitmap = RenderGlyph_Nativetext(pFont, glyph_index, pMatrix, + dest_width, anti_alias); + if (pGlyphBitmap) { + pSizeCache->m_GlyphMap.SetAt((void*)(uintptr_t)glyph_index, pGlyphBitmap); + return pGlyphBitmap; + } + } else { + pGlyphBitmap = RenderGlyph_Nativetext(pFont, glyph_index, pMatrix, + dest_width, anti_alias); + if (pGlyphBitmap) { + pSizeCache = new CFX_SizeGlyphCache; + m_SizeMap.SetAt(FaceGlyphsKey, pSizeCache); + pSizeCache->m_GlyphMap.SetAt((void*)(uintptr_t)glyph_index, pGlyphBitmap); + return pGlyphBitmap; + } + } + if (pFont->GetSubstFont()) + keygen.Generate(9, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000), + (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), + dest_width, anti_alias, pFont->GetSubstFont()->m_Weight, + pFont->GetSubstFont()->m_ItalicAngle, pFont->IsVertical()); + else + keygen.Generate(6, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000), + (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), + dest_width, anti_alias); + CFX_ByteStringC FaceGlyphsKey2(keygen.m_Key, keygen.m_KeyLen); + text_flags |= FXTEXT_NO_NATIVETEXT; + return LookUpGlyphBitmap(pFont, pMatrix, FaceGlyphsKey2, glyph_index, + bFontStyle, dest_width, anti_alias); #endif } -CFX_SizeGlyphCache::~CFX_SizeGlyphCache() -{ - FX_POSITION pos = m_GlyphMap.GetStartPosition(); - void* Key; - CFX_GlyphBitmap* pGlyphBitmap = NULL; - while(pos) { - m_GlyphMap.GetNextAssoc(pos, Key, (void*&)pGlyphBitmap); - delete pGlyphBitmap; - } - m_GlyphMap.RemoveAll(); +CFX_SizeGlyphCache::~CFX_SizeGlyphCache() { + FX_POSITION pos = m_GlyphMap.GetStartPosition(); + void* Key; + CFX_GlyphBitmap* pGlyphBitmap = NULL; + while (pos) { + m_GlyphMap.GetNextAssoc(pos, Key, (void*&)pGlyphBitmap); + delete pGlyphBitmap; + } + m_GlyphMap.RemoveAll(); } -#define CONTRAST_RAMP_STEP 1 -void CFX_Font::AdjustMMParams(int glyph_index, int dest_width, int weight) -{ - FXFT_MM_Var pMasters = NULL; - FXFT_Get_MM_Var(m_Face, &pMasters); - if (pMasters == NULL) { - return; - } - long coords[2]; - if (weight == 0) { - coords[0] = FXFT_Get_MM_Axis_Def(FXFT_Get_MM_Axis(pMasters, 0)) / 65536; - } else { - coords[0] = weight; - } - if (dest_width == 0) { - coords[1] = FXFT_Get_MM_Axis_Def(FXFT_Get_MM_Axis(pMasters, 1)) / 65536; - } else { - int min_param = FXFT_Get_MM_Axis_Min(FXFT_Get_MM_Axis(pMasters, 1)) / 65536; - int max_param = FXFT_Get_MM_Axis_Max(FXFT_Get_MM_Axis(pMasters, 1)) / 65536; - coords[1] = min_param; - int error = FXFT_Set_MM_Design_Coordinates(m_Face, 2, coords); - error = FXFT_Load_Glyph(m_Face, glyph_index, FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); - int min_width = FXFT_Get_Glyph_HoriAdvance(m_Face) * 1000 / FXFT_Get_Face_UnitsPerEM(m_Face); - coords[1] = max_param; - error = FXFT_Set_MM_Design_Coordinates(m_Face, 2, coords); - error = FXFT_Load_Glyph(m_Face, glyph_index, FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); - int max_width = FXFT_Get_Glyph_HoriAdvance(m_Face) * 1000 / FXFT_Get_Face_UnitsPerEM(m_Face); - if (max_width == min_width) { - return; - } - int param = min_param + (max_param - min_param) * (dest_width - min_width) / (max_width - min_width); - coords[1] = param; - } - FXFT_Free(m_Face, pMasters); - FXFT_Set_MM_Design_Coordinates(m_Face, 2, coords); +#define CONTRAST_RAMP_STEP 1 +void CFX_Font::AdjustMMParams(int glyph_index, int dest_width, int weight) { + FXFT_MM_Var pMasters = NULL; + FXFT_Get_MM_Var(m_Face, &pMasters); + if (pMasters == NULL) { + return; + } + long coords[2]; + if (weight == 0) { + coords[0] = FXFT_Get_MM_Axis_Def(FXFT_Get_MM_Axis(pMasters, 0)) / 65536; + } else { + coords[0] = weight; + } + if (dest_width == 0) { + coords[1] = FXFT_Get_MM_Axis_Def(FXFT_Get_MM_Axis(pMasters, 1)) / 65536; + } else { + int min_param = FXFT_Get_MM_Axis_Min(FXFT_Get_MM_Axis(pMasters, 1)) / 65536; + int max_param = FXFT_Get_MM_Axis_Max(FXFT_Get_MM_Axis(pMasters, 1)) / 65536; + coords[1] = min_param; + int error = FXFT_Set_MM_Design_Coordinates(m_Face, 2, coords); + error = FXFT_Load_Glyph( + m_Face, glyph_index, + FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); + int min_width = FXFT_Get_Glyph_HoriAdvance(m_Face) * 1000 / + FXFT_Get_Face_UnitsPerEM(m_Face); + coords[1] = max_param; + error = FXFT_Set_MM_Design_Coordinates(m_Face, 2, coords); + error = FXFT_Load_Glyph( + m_Face, glyph_index, + FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); + int max_width = FXFT_Get_Glyph_HoriAdvance(m_Face) * 1000 / + FXFT_Get_Face_UnitsPerEM(m_Face); + if (max_width == min_width) { + return; + } + int param = min_param + + (max_param - min_param) * (dest_width - min_width) / + (max_width - min_width); + coords[1] = param; + } + FXFT_Free(m_Face, pMasters); + FXFT_Set_MM_Design_Coordinates(m_Face, 2, coords); } static const size_t ANGLESKEW_ARRAY_SIZE = 30; static const char g_AngleSkew[ANGLESKEW_ARRAY_SIZE] = { - 0, 2, 3, 5, 7, 9, 11, 12, 14, 16, - 18, 19, 21, 23, 25, 27, 29, 31, 32, 34, - 36, 38, 40, 42, 45, 47, 49, 51, 53, 55, + 0, 2, 3, 5, 7, 9, 11, 12, 14, 16, 18, 19, 21, 23, 25, + 27, 29, 31, 32, 34, 36, 38, 40, 42, 45, 47, 49, 51, 53, 55, }; static const size_t WEIGHTPOW_ARRAY_SIZE = 100; static const uint8_t g_WeightPow[WEIGHTPOW_ARRAY_SIZE] = { - 0, 3, 6, 7, 8, 9, 11, 12, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 35, 36, 36, - 37, 37, 37, 38, 38, 38, 39, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 42, - 42, 43, 43, 43, 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 47, 47, - 47, 47, 48, 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 50, 51, 51, - 51, 51, 51, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, + 0, 3, 6, 7, 8, 9, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 35, 36, 36, 37, + 37, 37, 38, 38, 38, 39, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 42, + 42, 43, 43, 43, 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 47, + 47, 47, 47, 48, 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 50, + 51, 51, 51, 51, 51, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, }; static const uint8_t g_WeightPow_11[WEIGHTPOW_ARRAY_SIZE] = { - 0, 4, 7, 8, 9, 10, 12, 13, 15, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 39, 39, 40, 40, - 41, 41, 41, 42, 42, 42, 43, 43, 43, 44, 44, 44, 45, 45, 45, 46, 46, 46, - 46, 43, 47, 47, 48, 48, 48, 48, 45, 50, 50, 50, 46, 51, 51, 51, 52, 52, - 52, 52, 53, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55, 55, 56, 56, - 56, 56, 56, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58, + 0, 4, 7, 8, 9, 10, 12, 13, 15, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 39, 39, 40, 40, 41, + 41, 41, 42, 42, 42, 43, 43, 43, 44, 44, 44, 45, 45, 45, 46, 46, 46, + 46, 43, 47, 47, 48, 48, 48, 48, 45, 50, 50, 50, 46, 51, 51, 51, 52, + 52, 52, 52, 53, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55, 55, + 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58, }; static const uint8_t g_WeightPow_SHIFTJIS[WEIGHTPOW_ARRAY_SIZE] = { - 0, 0, 1, 2, 3, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 21, 22, 24, 26, 28, - 30, 32, 33, 35, 37, 39, 41, 43, 45, 48, 48, 48, 48, 49, 49, 49, 50, 50, 50, 50, - 51, 51, 51, 51, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 54, 54, 54, 54, 54, 55, 55, - 55, 55, 55, 56, 56, 56, 56, 56 , 56, 57, 57, 57 , 57 , 57, 57, 57, 58, 58, 58, 58, 58, - 58, 58, 59, 59, 59, 59, 59, 59, 59, 60, 60, 60, 60, 60, 60, 60, 60, + 0, 0, 1, 2, 3, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 21, + 22, 24, 26, 28, 30, 32, 33, 35, 37, 39, 41, 43, 45, 48, 48, 48, 48, + 49, 49, 49, 50, 50, 50, 50, 51, 51, 51, 51, 52, 52, 52, 52, 52, 53, + 53, 53, 53, 53, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 56, 56, 56, + 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58, 58, 58, + 59, 59, 59, 59, 59, 59, 59, 60, 60, 60, 60, 60, 60, 60, 60, }; -static void _GammaAdjust(uint8_t* pData, int nWid, int nHei, int src_pitch, const uint8_t* gammaTable) -{ - int count = nHei * src_pitch; - for(int i = 0; i < count; i++) { - pData[i] = gammaTable[pData[i]]; - } +static void _GammaAdjust(uint8_t* pData, + int nWid, + int nHei, + int src_pitch, + const uint8_t* gammaTable) { + int count = nHei * src_pitch; + for (int i = 0; i < count; i++) { + pData[i] = gammaTable[pData[i]]; + } } -static void _ContrastAdjust(uint8_t* pDataIn, uint8_t* pDataOut, int nWid, int nHei, int nSrcRowBytes, int nDstRowBytes) -{ - int col, row, temp; - int max = 0, min = 255; - FX_FLOAT rate; - for (row = 0; row < nHei; row ++) { - uint8_t* pRow = pDataIn + row * nSrcRowBytes; - for (col = 0; col < nWid; col++) { - temp = *pRow ++; - if (temp > max) { - max = temp; - } - if (temp < min) { - min = temp; - } - } - } - temp = max - min; - if (0 == temp || 255 == temp) { - int rowbytes = FXSYS_abs(nSrcRowBytes) > nDstRowBytes ? nDstRowBytes : FXSYS_abs(nSrcRowBytes); - for (row = 0; row < nHei; row ++) { - FXSYS_memcpy(pDataOut + row * nDstRowBytes, pDataIn + row * nSrcRowBytes, rowbytes); - } - return; - } - rate = 255.f / temp; - for (row = 0; row < nHei; row ++) { - uint8_t* pSrcRow = pDataIn + row * nSrcRowBytes; - uint8_t* pDstRow = pDataOut + row * nDstRowBytes; - for (col = 0; col < nWid; col ++) { - temp = (int)((*(pSrcRow++) - min) * rate + 0.5); - if (temp > 255) { - temp = 255; - } else if (temp < 0) { - temp = 0; - } - *pDstRow ++ = (uint8_t)temp; - } - } +static void _ContrastAdjust(uint8_t* pDataIn, + uint8_t* pDataOut, + int nWid, + int nHei, + int nSrcRowBytes, + int nDstRowBytes) { + int col, row, temp; + int max = 0, min = 255; + FX_FLOAT rate; + for (row = 0; row < nHei; row++) { + uint8_t* pRow = pDataIn + row * nSrcRowBytes; + for (col = 0; col < nWid; col++) { + temp = *pRow++; + if (temp > max) { + max = temp; + } + if (temp < min) { + min = temp; + } + } + } + temp = max - min; + if (0 == temp || 255 == temp) { + int rowbytes = FXSYS_abs(nSrcRowBytes) > nDstRowBytes + ? nDstRowBytes + : FXSYS_abs(nSrcRowBytes); + for (row = 0; row < nHei; row++) { + FXSYS_memcpy(pDataOut + row * nDstRowBytes, pDataIn + row * nSrcRowBytes, + rowbytes); + } + return; + } + rate = 255.f / temp; + for (row = 0; row < nHei; row++) { + uint8_t* pSrcRow = pDataIn + row * nSrcRowBytes; + uint8_t* pDstRow = pDataOut + row * nDstRowBytes; + for (col = 0; col < nWid; col++) { + temp = (int)((*(pSrcRow++) - min) * rate + 0.5); + if (temp > 255) { + temp = 255; + } else if (temp < 0) { + temp = 0; + } + *pDstRow++ = (uint8_t)temp; + } + } } -CFX_GlyphBitmap* CFX_FaceCache::RenderGlyph(CFX_Font* pFont, FX_DWORD glyph_index, FX_BOOL bFontStyle, - const CFX_AffineMatrix* pMatrix, int dest_width, int anti_alias) -{ - if (m_Face == NULL) { - return NULL; - } - FXFT_Matrix ft_matrix; - ft_matrix.xx = (signed long)(pMatrix->GetA() / 64 * 65536); - ft_matrix.xy = (signed long)(pMatrix->GetC() / 64 * 65536); - ft_matrix.yx = (signed long)(pMatrix->GetB() / 64 * 65536); - ft_matrix.yy = (signed long)(pMatrix->GetD() / 64 * 65536); - FX_BOOL bUseCJKSubFont = FALSE; - const CFX_SubstFont* pSubstFont = pFont->GetSubstFont(); - if (pSubstFont) { - bUseCJKSubFont = pSubstFont->m_bSubstOfCJK && bFontStyle; - int skew = 0; - if (bUseCJKSubFont) { - skew = pSubstFont->m_bItlicCJK ? -15 : 0; - } else { - skew = pSubstFont->m_ItalicAngle; - } - if (skew) { - skew = skew <= -ANGLESKEW_ARRAY_SIZE ? -58 : -g_AngleSkew[-skew]; - if (pFont->IsVertical()) { - ft_matrix.yx += ft_matrix.yy * skew / 100; - } else { - ft_matrix.xy += -ft_matrix.xx * skew / 100; - } - } - if (pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) { - pFont->AdjustMMParams(glyph_index, dest_width, pFont->GetSubstFont()->m_Weight); - } - } - ScopedFontTransform scoped_transform(m_Face, &ft_matrix); - int load_flags = (m_Face->face_flags & FT_FACE_FLAG_SFNT) ? FXFT_LOAD_NO_BITMAP : (FXFT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING); - int error = FXFT_Load_Glyph(m_Face, glyph_index, load_flags); - if (error) { - //if an error is returned, try to reload glyphs without hinting. - if (load_flags & FT_LOAD_NO_HINTING || load_flags & FT_LOAD_NO_SCALE) { - return NULL; - } - - load_flags |= FT_LOAD_NO_HINTING; - error = FXFT_Load_Glyph(m_Face, glyph_index, load_flags); - - if (error) { - return NULL; - } - } - int weight = 0; +CFX_GlyphBitmap* CFX_FaceCache::RenderGlyph(CFX_Font* pFont, + FX_DWORD glyph_index, + FX_BOOL bFontStyle, + const CFX_AffineMatrix* pMatrix, + int dest_width, + int anti_alias) { + if (m_Face == NULL) { + return NULL; + } + FXFT_Matrix ft_matrix; + ft_matrix.xx = (signed long)(pMatrix->GetA() / 64 * 65536); + ft_matrix.xy = (signed long)(pMatrix->GetC() / 64 * 65536); + ft_matrix.yx = (signed long)(pMatrix->GetB() / 64 * 65536); + ft_matrix.yy = (signed long)(pMatrix->GetD() / 64 * 65536); + FX_BOOL bUseCJKSubFont = FALSE; + const CFX_SubstFont* pSubstFont = pFont->GetSubstFont(); + if (pSubstFont) { + bUseCJKSubFont = pSubstFont->m_bSubstOfCJK && bFontStyle; + int skew = 0; if (bUseCJKSubFont) { - weight = pSubstFont->m_WeightCJK; + skew = pSubstFont->m_bItlicCJK ? -15 : 0; } else { - weight = pSubstFont ? pSubstFont->m_Weight : 0; - } - if (pSubstFont && !(pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) && weight > 400) { - int index = (weight - 400) / 10; - if (index >= WEIGHTPOW_ARRAY_SIZE) { - return NULL; - } - int level = 0; - if (pSubstFont->m_Charset == FXFONT_SHIFTJIS_CHARSET) { - level = g_WeightPow_SHIFTJIS[index] * 2 * (FXSYS_abs((int)(ft_matrix.xx)) + FXSYS_abs((int)(ft_matrix.xy))) / 36655; - } else { - level = g_WeightPow_11[index] * (FXSYS_abs((int)(ft_matrix.xx)) + FXSYS_abs((int)(ft_matrix.xy))) / 36655; - } - FXFT_Outline_Embolden(FXFT_Get_Glyph_Outline(m_Face), level); + skew = pSubstFont->m_ItalicAngle; + } + if (skew) { + skew = skew <= -ANGLESKEW_ARRAY_SIZE ? -58 : -g_AngleSkew[-skew]; + if (pFont->IsVertical()) { + ft_matrix.yx += ft_matrix.yy * skew / 100; + } else { + ft_matrix.xy += -ft_matrix.xx * skew / 100; + } + } + if (pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) { + pFont->AdjustMMParams(glyph_index, dest_width, + pFont->GetSubstFont()->m_Weight); + } + } + ScopedFontTransform scoped_transform(m_Face, &ft_matrix); + int load_flags = (m_Face->face_flags & FT_FACE_FLAG_SFNT) + ? FXFT_LOAD_NO_BITMAP + : (FXFT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING); + int error = FXFT_Load_Glyph(m_Face, glyph_index, load_flags); + if (error) { + // if an error is returned, try to reload glyphs without hinting. + if (load_flags & FT_LOAD_NO_HINTING || load_flags & FT_LOAD_NO_SCALE) { + return NULL; } - FXFT_Library_SetLcdFilter(CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary, FT_LCD_FILTER_DEFAULT); - error = FXFT_Render_Glyph(m_Face, anti_alias); + + load_flags |= FT_LOAD_NO_HINTING; + error = FXFT_Load_Glyph(m_Face, glyph_index, load_flags); + if (error) { - return NULL; - } - int bmwidth = FXFT_Get_Bitmap_Width(FXFT_Get_Glyph_Bitmap(m_Face)); - int bmheight = FXFT_Get_Bitmap_Rows(FXFT_Get_Glyph_Bitmap(m_Face)); - if (bmwidth > 2048 || bmheight > 2048) { - return NULL; - } - int dib_width = bmwidth; - CFX_GlyphBitmap* pGlyphBitmap = new CFX_GlyphBitmap; - pGlyphBitmap->m_Bitmap.Create(dib_width, bmheight, - anti_alias == FXFT_RENDER_MODE_MONO ? FXDIB_1bppMask : FXDIB_8bppMask); - pGlyphBitmap->m_Left = FXFT_Get_Glyph_BitmapLeft(m_Face); - pGlyphBitmap->m_Top = FXFT_Get_Glyph_BitmapTop(m_Face); - int dest_pitch = pGlyphBitmap->m_Bitmap.GetPitch(); - int src_pitch = FXFT_Get_Bitmap_Pitch(FXFT_Get_Glyph_Bitmap(m_Face)); - uint8_t* pDestBuf = pGlyphBitmap->m_Bitmap.GetBuffer(); - uint8_t* pSrcBuf = (uint8_t*)FXFT_Get_Bitmap_Buffer(FXFT_Get_Glyph_Bitmap(m_Face)); - if (anti_alias != FXFT_RENDER_MODE_MONO && FXFT_Get_Bitmap_PixelMode(FXFT_Get_Glyph_Bitmap(m_Face)) == FXFT_PIXEL_MODE_MONO) { - int bytes = anti_alias == FXFT_RENDER_MODE_LCD ? 3 : 1; - for(int i = 0; i < bmheight; i++) - for(int n = 0; n < bmwidth; n++) { - uint8_t data = (pSrcBuf[i * src_pitch + n / 8] & (0x80 >> (n % 8))) ? 255 : 0; - for (int b = 0; b < bytes; b ++) { - pDestBuf[i * dest_pitch + n * bytes + b] = data; - } - } + return NULL; + } + } + int weight = 0; + if (bUseCJKSubFont) { + weight = pSubstFont->m_WeightCJK; + } else { + weight = pSubstFont ? pSubstFont->m_Weight : 0; + } + if (pSubstFont && !(pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) && + weight > 400) { + int index = (weight - 400) / 10; + if (index >= WEIGHTPOW_ARRAY_SIZE) { + return NULL; + } + int level = 0; + if (pSubstFont->m_Charset == FXFONT_SHIFTJIS_CHARSET) { + level = + g_WeightPow_SHIFTJIS[index] * 2 * + (FXSYS_abs((int)(ft_matrix.xx)) + FXSYS_abs((int)(ft_matrix.xy))) / + 36655; } else { - FXSYS_memset(pDestBuf, 0, dest_pitch * bmheight); - if (anti_alias == FXFT_RENDER_MODE_MONO && FXFT_Get_Bitmap_PixelMode(FXFT_Get_Glyph_Bitmap(m_Face)) == FXFT_PIXEL_MODE_MONO) { - int rowbytes = FXSYS_abs(src_pitch) > dest_pitch ? dest_pitch : FXSYS_abs(src_pitch); - for (int row = 0; row < bmheight; row ++) { - FXSYS_memcpy(pDestBuf + row * dest_pitch, pSrcBuf + row * src_pitch, rowbytes); - } - } else { - _ContrastAdjust(pSrcBuf, pDestBuf, bmwidth, bmheight, src_pitch, dest_pitch); - _GammaAdjust(pDestBuf, bmwidth, bmheight, dest_pitch, CFX_GEModule::Get()->GetTextGammaTable()); + level = g_WeightPow_11[index] * (FXSYS_abs((int)(ft_matrix.xx)) + + FXSYS_abs((int)(ft_matrix.xy))) / + 36655; + } + FXFT_Outline_Embolden(FXFT_Get_Glyph_Outline(m_Face), level); + } + FXFT_Library_SetLcdFilter(CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary, + FT_LCD_FILTER_DEFAULT); + error = FXFT_Render_Glyph(m_Face, anti_alias); + if (error) { + return NULL; + } + int bmwidth = FXFT_Get_Bitmap_Width(FXFT_Get_Glyph_Bitmap(m_Face)); + int bmheight = FXFT_Get_Bitmap_Rows(FXFT_Get_Glyph_Bitmap(m_Face)); + if (bmwidth > 2048 || bmheight > 2048) { + return NULL; + } + int dib_width = bmwidth; + CFX_GlyphBitmap* pGlyphBitmap = new CFX_GlyphBitmap; + pGlyphBitmap->m_Bitmap.Create( + dib_width, bmheight, + anti_alias == FXFT_RENDER_MODE_MONO ? FXDIB_1bppMask : FXDIB_8bppMask); + pGlyphBitmap->m_Left = FXFT_Get_Glyph_BitmapLeft(m_Face); + pGlyphBitmap->m_Top = FXFT_Get_Glyph_BitmapTop(m_Face); + int dest_pitch = pGlyphBitmap->m_Bitmap.GetPitch(); + int src_pitch = FXFT_Get_Bitmap_Pitch(FXFT_Get_Glyph_Bitmap(m_Face)); + uint8_t* pDestBuf = pGlyphBitmap->m_Bitmap.GetBuffer(); + uint8_t* pSrcBuf = + (uint8_t*)FXFT_Get_Bitmap_Buffer(FXFT_Get_Glyph_Bitmap(m_Face)); + if (anti_alias != FXFT_RENDER_MODE_MONO && + FXFT_Get_Bitmap_PixelMode(FXFT_Get_Glyph_Bitmap(m_Face)) == + FXFT_PIXEL_MODE_MONO) { + int bytes = anti_alias == FXFT_RENDER_MODE_LCD ? 3 : 1; + for (int i = 0; i < bmheight; i++) + for (int n = 0; n < bmwidth; n++) { + uint8_t data = + (pSrcBuf[i * src_pitch + n / 8] & (0x80 >> (n % 8))) ? 255 : 0; + for (int b = 0; b < bytes; b++) { + pDestBuf[i * dest_pitch + n * bytes + b] = data; } + } + } else { + FXSYS_memset(pDestBuf, 0, dest_pitch * bmheight); + if (anti_alias == FXFT_RENDER_MODE_MONO && + FXFT_Get_Bitmap_PixelMode(FXFT_Get_Glyph_Bitmap(m_Face)) == + FXFT_PIXEL_MODE_MONO) { + int rowbytes = + FXSYS_abs(src_pitch) > dest_pitch ? dest_pitch : FXSYS_abs(src_pitch); + for (int row = 0; row < bmheight; row++) { + FXSYS_memcpy(pDestBuf + row * dest_pitch, pSrcBuf + row * src_pitch, + rowbytes); + } + } else { + _ContrastAdjust(pSrcBuf, pDestBuf, bmwidth, bmheight, src_pitch, + dest_pitch); + _GammaAdjust(pDestBuf, bmwidth, bmheight, dest_pitch, + CFX_GEModule::Get()->GetTextGammaTable()); } - return pGlyphBitmap; + } + return pGlyphBitmap; } -FX_BOOL _OutputGlyph(void* dib, int x, int y, CFX_Font* pFont, - int glyph_index, FX_ARGB argb) -{ - CFX_DIBitmap* pDib = (CFX_DIBitmap*)dib; - FXFT_Face face = pFont->GetFace(); - int error = FXFT_Load_Glyph(face, glyph_index, FXFT_LOAD_NO_BITMAP); - if (error) { - return FALSE; - } - error = FXFT_Render_Glyph(face, FXFT_RENDER_MODE_NORMAL); - if (error) { - return FALSE; - } - int bmwidth = FXFT_Get_Bitmap_Width(FXFT_Get_Glyph_Bitmap(face)); - int bmheight = FXFT_Get_Bitmap_Rows(FXFT_Get_Glyph_Bitmap(face)); - int left = FXFT_Get_Glyph_BitmapLeft(face); - int top = FXFT_Get_Glyph_BitmapTop(face); - const uint8_t* src_buf = (const uint8_t*)FXFT_Get_Bitmap_Buffer(FXFT_Get_Glyph_Bitmap(face)); - int src_pitch = FXFT_Get_Bitmap_Pitch(FXFT_Get_Glyph_Bitmap(face)); - CFX_DIBitmap mask; - mask.Create(bmwidth, bmheight, FXDIB_8bppMask); - uint8_t* dest_buf = mask.GetBuffer(); - int dest_pitch = mask.GetPitch(); - for (int row = 0; row < bmheight; row ++) { - const uint8_t* src_scan = src_buf + row * src_pitch; - uint8_t* dest_scan = dest_buf + row * dest_pitch; - FXSYS_memcpy(dest_scan, src_scan, dest_pitch); - } - pDib->CompositeMask(x + left, y - top, bmwidth, bmheight, &mask, argb, 0, 0); - return TRUE; +FX_BOOL _OutputGlyph(void* dib, + int x, + int y, + CFX_Font* pFont, + int glyph_index, + FX_ARGB argb) { + CFX_DIBitmap* pDib = (CFX_DIBitmap*)dib; + FXFT_Face face = pFont->GetFace(); + int error = FXFT_Load_Glyph(face, glyph_index, FXFT_LOAD_NO_BITMAP); + if (error) { + return FALSE; + } + error = FXFT_Render_Glyph(face, FXFT_RENDER_MODE_NORMAL); + if (error) { + return FALSE; + } + int bmwidth = FXFT_Get_Bitmap_Width(FXFT_Get_Glyph_Bitmap(face)); + int bmheight = FXFT_Get_Bitmap_Rows(FXFT_Get_Glyph_Bitmap(face)); + int left = FXFT_Get_Glyph_BitmapLeft(face); + int top = FXFT_Get_Glyph_BitmapTop(face); + const uint8_t* src_buf = + (const uint8_t*)FXFT_Get_Bitmap_Buffer(FXFT_Get_Glyph_Bitmap(face)); + int src_pitch = FXFT_Get_Bitmap_Pitch(FXFT_Get_Glyph_Bitmap(face)); + CFX_DIBitmap mask; + mask.Create(bmwidth, bmheight, FXDIB_8bppMask); + uint8_t* dest_buf = mask.GetBuffer(); + int dest_pitch = mask.GetPitch(); + for (int row = 0; row < bmheight; row++) { + const uint8_t* src_scan = src_buf + row * src_pitch; + uint8_t* dest_scan = dest_buf + row * dest_pitch; + FXSYS_memcpy(dest_scan, src_scan, dest_pitch); + } + pDib->CompositeMask(x + left, y - top, bmwidth, bmheight, &mask, argb, 0, 0); + return TRUE; } -FX_BOOL OutputText(void* dib, int x, int y, CFX_Font* pFont, double font_size, - CFX_AffineMatrix* pText_matrix, unsigned short const* text, unsigned long argb) -{ - if (!pFont) { - return FALSE; - } - FXFT_Face face = pFont->GetFace(); - FXFT_Select_Charmap(pFont->m_Face, FXFT_ENCODING_UNICODE); - if (pText_matrix) { - FXFT_Matrix ft_matrix; - ft_matrix.xx = (signed long)(pText_matrix->a / 64 * 65536); - ft_matrix.xy = (signed long)(pText_matrix->c / 64 * 65536); - ft_matrix.yx = (signed long)(pText_matrix->b / 64 * 65536); - ft_matrix.yy = (signed long)(pText_matrix->d / 64 * 65536); - FXFT_Set_Transform(face, &ft_matrix, 0); - } - FX_FLOAT x_pos = 0; - for (; *text != 0; text ++) { - FX_WCHAR unicode = *text; - int glyph_index = FXFT_Get_Char_Index(pFont->m_Face, unicode); - if (glyph_index <= 0) { - continue; - } - int err = FXFT_Load_Glyph(pFont->m_Face, glyph_index, FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); - if (err) { - continue; - } - int w = FXFT_Get_Glyph_HoriAdvance(pFont->m_Face); - int em = FXFT_Get_Face_UnitsPerEM(pFont->m_Face); - FX_FLOAT x1, y1; - pText_matrix->Transform(x_pos, 0, x1, y1); - _OutputGlyph(dib, (int)x1 + x, (int) - y1 + y, pFont, - glyph_index, argb); - x_pos += (FX_FLOAT)w / em; - } - if (pText_matrix) - ResetTransform(face); - return TRUE; +FX_BOOL OutputText(void* dib, + int x, + int y, + CFX_Font* pFont, + double font_size, + CFX_AffineMatrix* pText_matrix, + unsigned short const* text, + unsigned long argb) { + if (!pFont) { + return FALSE; + } + FXFT_Face face = pFont->GetFace(); + FXFT_Select_Charmap(pFont->m_Face, FXFT_ENCODING_UNICODE); + if (pText_matrix) { + FXFT_Matrix ft_matrix; + ft_matrix.xx = (signed long)(pText_matrix->a / 64 * 65536); + ft_matrix.xy = (signed long)(pText_matrix->c / 64 * 65536); + ft_matrix.yx = (signed long)(pText_matrix->b / 64 * 65536); + ft_matrix.yy = (signed long)(pText_matrix->d / 64 * 65536); + FXFT_Set_Transform(face, &ft_matrix, 0); + } + FX_FLOAT x_pos = 0; + for (; *text != 0; text++) { + FX_WCHAR unicode = *text; + int glyph_index = FXFT_Get_Char_Index(pFont->m_Face, unicode); + if (glyph_index <= 0) { + continue; + } + int err = FXFT_Load_Glyph( + pFont->m_Face, glyph_index, + FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); + if (err) { + continue; + } + int w = FXFT_Get_Glyph_HoriAdvance(pFont->m_Face); + int em = FXFT_Get_Face_UnitsPerEM(pFont->m_Face); + FX_FLOAT x1, y1; + pText_matrix->Transform(x_pos, 0, x1, y1); + _OutputGlyph(dib, (int)x1 + x, (int)-y1 + y, pFont, glyph_index, argb); + x_pos += (FX_FLOAT)w / em; + } + if (pText_matrix) + ResetTransform(face); + return TRUE; } -FX_BOOL OutputGlyph(void* dib, int x, int y, CFX_Font* pFont, double font_size, - CFX_AffineMatrix* pMatrix, unsigned long glyph_index, unsigned long argb) -{ - FXFT_Matrix ft_matrix; - if (pMatrix) { - ft_matrix.xx = (signed long)(pMatrix->a * font_size / 64 * 65536); - ft_matrix.xy = (signed long)(pMatrix->c * font_size / 64 * 65536); - ft_matrix.yx = (signed long)(pMatrix->b * font_size / 64 * 65536); - ft_matrix.yy = (signed long)(pMatrix->d * font_size / 64 * 65536); - } else { - ft_matrix.xx = (signed long)(font_size / 64 * 65536); - ft_matrix.xy = ft_matrix.yx = 0; - ft_matrix.yy = (signed long)(font_size / 64 * 65536); - } - ScopedFontTransform scoped_transform(pFont->m_Face, &ft_matrix); - FX_BOOL ret = _OutputGlyph(dib, x, y, pFont, - glyph_index, argb); - return ret; +FX_BOOL OutputGlyph(void* dib, + int x, + int y, + CFX_Font* pFont, + double font_size, + CFX_AffineMatrix* pMatrix, + unsigned long glyph_index, + unsigned long argb) { + FXFT_Matrix ft_matrix; + if (pMatrix) { + ft_matrix.xx = (signed long)(pMatrix->a * font_size / 64 * 65536); + ft_matrix.xy = (signed long)(pMatrix->c * font_size / 64 * 65536); + ft_matrix.yx = (signed long)(pMatrix->b * font_size / 64 * 65536); + ft_matrix.yy = (signed long)(pMatrix->d * font_size / 64 * 65536); + } else { + ft_matrix.xx = (signed long)(font_size / 64 * 65536); + ft_matrix.xy = ft_matrix.yx = 0; + ft_matrix.yy = (signed long)(font_size / 64 * 65536); + } + ScopedFontTransform scoped_transform(pFont->m_Face, &ft_matrix); + FX_BOOL ret = _OutputGlyph(dib, x, y, pFont, glyph_index, argb); + return ret; } -const CFX_PathData* CFX_FaceCache::LoadGlyphPath(CFX_Font* pFont, FX_DWORD glyph_index, int dest_width) -{ - if (m_Face == NULL || glyph_index == (FX_DWORD) - 1) { - return NULL; - } - CFX_PathData* pGlyphPath = NULL; - void* key; - if (pFont->GetSubstFont()) - key = (void*)(uintptr_t)(glyph_index + ((pFont->GetSubstFont()->m_Weight / 16) << 15) + - ((pFont->GetSubstFont()->m_ItalicAngle / 2) << 21) + ((dest_width / 16) << 25) + - (pFont->IsVertical() << 31)); - else { - key = (void*)(uintptr_t)glyph_index; - } - if (m_PathMap.Lookup(key, (void*&)pGlyphPath)) { - return pGlyphPath; - } - pGlyphPath = pFont->LoadGlyphPath(glyph_index, dest_width); - m_PathMap.SetAt(key, pGlyphPath); +const CFX_PathData* CFX_FaceCache::LoadGlyphPath(CFX_Font* pFont, + FX_DWORD glyph_index, + int dest_width) { + if (m_Face == NULL || glyph_index == (FX_DWORD)-1) { + return NULL; + } + CFX_PathData* pGlyphPath = NULL; + void* key; + if (pFont->GetSubstFont()) + key = (void*)(uintptr_t)( + glyph_index + ((pFont->GetSubstFont()->m_Weight / 16) << 15) + + ((pFont->GetSubstFont()->m_ItalicAngle / 2) << 21) + + ((dest_width / 16) << 25) + (pFont->IsVertical() << 31)); + else { + key = (void*)(uintptr_t)glyph_index; + } + if (m_PathMap.Lookup(key, (void*&)pGlyphPath)) { return pGlyphPath; + } + pGlyphPath = pFont->LoadGlyphPath(glyph_index, dest_width); + m_PathMap.SetAt(key, pGlyphPath); + return pGlyphPath; } typedef struct { - FX_BOOL m_bCount; - int m_PointCount; - FX_PATHPOINT* m_pPoints; - int m_CurX; - int m_CurY; - FX_FLOAT m_CoordUnit; + FX_BOOL m_bCount; + int m_PointCount; + FX_PATHPOINT* m_pPoints; + int m_CurX; + int m_CurY; + FX_FLOAT m_CoordUnit; } OUTLINE_PARAMS; -void _Outline_CheckEmptyContour(OUTLINE_PARAMS* param) -{ - if (param->m_PointCount >= 2 && param->m_pPoints[param->m_PointCount - 2].m_Flag == FXPT_MOVETO && - param->m_pPoints[param->m_PointCount - 2].m_PointX == param->m_pPoints[param->m_PointCount - 1].m_PointX && - param->m_pPoints[param->m_PointCount - 2].m_PointY == param->m_pPoints[param->m_PointCount - 1].m_PointY) { - param->m_PointCount -= 2; - } - if (param->m_PointCount >= 4 && param->m_pPoints[param->m_PointCount - 4].m_Flag == FXPT_MOVETO && - param->m_pPoints[param->m_PointCount - 3].m_Flag == FXPT_BEZIERTO && - param->m_pPoints[param->m_PointCount - 3].m_PointX == param->m_pPoints[param->m_PointCount - 4].m_PointX && - param->m_pPoints[param->m_PointCount - 3].m_PointY == param->m_pPoints[param->m_PointCount - 4].m_PointY && - param->m_pPoints[param->m_PointCount - 2].m_PointX == param->m_pPoints[param->m_PointCount - 4].m_PointX && - param->m_pPoints[param->m_PointCount - 2].m_PointY == param->m_pPoints[param->m_PointCount - 4].m_PointY && - param->m_pPoints[param->m_PointCount - 1].m_PointX == param->m_pPoints[param->m_PointCount - 4].m_PointX && - param->m_pPoints[param->m_PointCount - 1].m_PointY == param->m_pPoints[param->m_PointCount - 4].m_PointY) { - param->m_PointCount -= 4; - } +void _Outline_CheckEmptyContour(OUTLINE_PARAMS* param) { + if (param->m_PointCount >= 2 && + param->m_pPoints[param->m_PointCount - 2].m_Flag == FXPT_MOVETO && + param->m_pPoints[param->m_PointCount - 2].m_PointX == + param->m_pPoints[param->m_PointCount - 1].m_PointX && + param->m_pPoints[param->m_PointCount - 2].m_PointY == + param->m_pPoints[param->m_PointCount - 1].m_PointY) { + param->m_PointCount -= 2; + } + if (param->m_PointCount >= 4 && + param->m_pPoints[param->m_PointCount - 4].m_Flag == FXPT_MOVETO && + param->m_pPoints[param->m_PointCount - 3].m_Flag == FXPT_BEZIERTO && + param->m_pPoints[param->m_PointCount - 3].m_PointX == + param->m_pPoints[param->m_PointCount - 4].m_PointX && + param->m_pPoints[param->m_PointCount - 3].m_PointY == + param->m_pPoints[param->m_PointCount - 4].m_PointY && + param->m_pPoints[param->m_PointCount - 2].m_PointX == + param->m_pPoints[param->m_PointCount - 4].m_PointX && + param->m_pPoints[param->m_PointCount - 2].m_PointY == + param->m_pPoints[param->m_PointCount - 4].m_PointY && + param->m_pPoints[param->m_PointCount - 1].m_PointX == + param->m_pPoints[param->m_PointCount - 4].m_PointX && + param->m_pPoints[param->m_PointCount - 1].m_PointY == + param->m_pPoints[param->m_PointCount - 4].m_PointY) { + param->m_PointCount -= 4; + } } extern "C" { - static int _Outline_MoveTo(const FXFT_Vector* to, void* user) - { - OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user; - if (!param->m_bCount) { - _Outline_CheckEmptyContour(param); - param->m_pPoints[param->m_PointCount].m_PointX = to->x / param->m_CoordUnit; - param->m_pPoints[param->m_PointCount].m_PointY = to->y / param->m_CoordUnit; - param->m_pPoints[param->m_PointCount].m_Flag = FXPT_MOVETO; - param->m_CurX = to->x; - param->m_CurY = to->y; - if (param->m_PointCount) { - param->m_pPoints[param->m_PointCount - 1].m_Flag |= FXPT_CLOSEFIGURE; - } - } - param->m_PointCount ++; - return 0; - } +static int _Outline_MoveTo(const FXFT_Vector* to, void* user) { + OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user; + if (!param->m_bCount) { + _Outline_CheckEmptyContour(param); + param->m_pPoints[param->m_PointCount].m_PointX = to->x / param->m_CoordUnit; + param->m_pPoints[param->m_PointCount].m_PointY = to->y / param->m_CoordUnit; + param->m_pPoints[param->m_PointCount].m_Flag = FXPT_MOVETO; + param->m_CurX = to->x; + param->m_CurY = to->y; + if (param->m_PointCount) { + param->m_pPoints[param->m_PointCount - 1].m_Flag |= FXPT_CLOSEFIGURE; + } + } + param->m_PointCount++; + return 0; +} }; extern "C" { - static int _Outline_LineTo(const FXFT_Vector* to, void* user) - { - OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user; - if (!param->m_bCount) { - param->m_pPoints[param->m_PointCount].m_PointX = to->x / param->m_CoordUnit; - param->m_pPoints[param->m_PointCount].m_PointY = to->y / param->m_CoordUnit; - param->m_pPoints[param->m_PointCount].m_Flag = FXPT_LINETO; - param->m_CurX = to->x; - param->m_CurY = to->y; - } - param->m_PointCount ++; - return 0; - } +static int _Outline_LineTo(const FXFT_Vector* to, void* user) { + OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user; + if (!param->m_bCount) { + param->m_pPoints[param->m_PointCount].m_PointX = to->x / param->m_CoordUnit; + param->m_pPoints[param->m_PointCount].m_PointY = to->y / param->m_CoordUnit; + param->m_pPoints[param->m_PointCount].m_Flag = FXPT_LINETO; + param->m_CurX = to->x; + param->m_CurY = to->y; + } + param->m_PointCount++; + return 0; +} }; extern "C" { - static int _Outline_ConicTo(const FXFT_Vector* control, const FXFT_Vector* to, void* user) - { - OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user; - if (!param->m_bCount) { - param->m_pPoints[param->m_PointCount].m_PointX = (param->m_CurX + (control->x - param->m_CurX) * 2 / 3) / param->m_CoordUnit; - param->m_pPoints[param->m_PointCount].m_PointY = (param->m_CurY + (control->y - param->m_CurY) * 2 / 3) / param->m_CoordUnit; - param->m_pPoints[param->m_PointCount].m_Flag = FXPT_BEZIERTO; - param->m_pPoints[param->m_PointCount + 1].m_PointX = (control->x + (to->x - control->x) / 3) / param->m_CoordUnit; - param->m_pPoints[param->m_PointCount + 1].m_PointY = (control->y + (to->y - control->y) / 3) / param->m_CoordUnit; - param->m_pPoints[param->m_PointCount + 1].m_Flag = FXPT_BEZIERTO; - param->m_pPoints[param->m_PointCount + 2].m_PointX = to->x / param->m_CoordUnit; - param->m_pPoints[param->m_PointCount + 2].m_PointY = to->y / param->m_CoordUnit; - param->m_pPoints[param->m_PointCount + 2].m_Flag = FXPT_BEZIERTO; - param->m_CurX = to->x; - param->m_CurY = to->y; - } - param->m_PointCount += 3; - return 0; - } +static int _Outline_ConicTo(const FXFT_Vector* control, + const FXFT_Vector* to, + void* user) { + OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user; + if (!param->m_bCount) { + param->m_pPoints[param->m_PointCount].m_PointX = + (param->m_CurX + (control->x - param->m_CurX) * 2 / 3) / + param->m_CoordUnit; + param->m_pPoints[param->m_PointCount].m_PointY = + (param->m_CurY + (control->y - param->m_CurY) * 2 / 3) / + param->m_CoordUnit; + param->m_pPoints[param->m_PointCount].m_Flag = FXPT_BEZIERTO; + param->m_pPoints[param->m_PointCount + 1].m_PointX = + (control->x + (to->x - control->x) / 3) / param->m_CoordUnit; + param->m_pPoints[param->m_PointCount + 1].m_PointY = + (control->y + (to->y - control->y) / 3) / param->m_CoordUnit; + param->m_pPoints[param->m_PointCount + 1].m_Flag = FXPT_BEZIERTO; + param->m_pPoints[param->m_PointCount + 2].m_PointX = + to->x / param->m_CoordUnit; + param->m_pPoints[param->m_PointCount + 2].m_PointY = + to->y / param->m_CoordUnit; + param->m_pPoints[param->m_PointCount + 2].m_Flag = FXPT_BEZIERTO; + param->m_CurX = to->x; + param->m_CurY = to->y; + } + param->m_PointCount += 3; + return 0; +} }; extern "C" { - static int _Outline_CubicTo(const FXFT_Vector* control1, const FXFT_Vector* control2, const FXFT_Vector* to, void* user) - { - OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user; - if (!param->m_bCount) { - param->m_pPoints[param->m_PointCount].m_PointX = control1->x / param->m_CoordUnit; - param->m_pPoints[param->m_PointCount].m_PointY = control1->y / param->m_CoordUnit; - param->m_pPoints[param->m_PointCount].m_Flag = FXPT_BEZIERTO; - param->m_pPoints[param->m_PointCount + 1].m_PointX = control2->x / param->m_CoordUnit; - param->m_pPoints[param->m_PointCount + 1].m_PointY = control2->y / param->m_CoordUnit; - param->m_pPoints[param->m_PointCount + 1].m_Flag = FXPT_BEZIERTO; - param->m_pPoints[param->m_PointCount + 2].m_PointX = to->x / param->m_CoordUnit; - param->m_pPoints[param->m_PointCount + 2].m_PointY = to->y / param->m_CoordUnit; - param->m_pPoints[param->m_PointCount + 2].m_Flag = FXPT_BEZIERTO; - param->m_CurX = to->x; - param->m_CurY = to->y; - } - param->m_PointCount += 3; - return 0; - } +static int _Outline_CubicTo(const FXFT_Vector* control1, + const FXFT_Vector* control2, + const FXFT_Vector* to, + void* user) { + OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user; + if (!param->m_bCount) { + param->m_pPoints[param->m_PointCount].m_PointX = + control1->x / param->m_CoordUnit; + param->m_pPoints[param->m_PointCount].m_PointY = + control1->y / param->m_CoordUnit; + param->m_pPoints[param->m_PointCount].m_Flag = FXPT_BEZIERTO; + param->m_pPoints[param->m_PointCount + 1].m_PointX = + control2->x / param->m_CoordUnit; + param->m_pPoints[param->m_PointCount + 1].m_PointY = + control2->y / param->m_CoordUnit; + param->m_pPoints[param->m_PointCount + 1].m_Flag = FXPT_BEZIERTO; + param->m_pPoints[param->m_PointCount + 2].m_PointX = + to->x / param->m_CoordUnit; + param->m_pPoints[param->m_PointCount + 2].m_PointY = + to->y / param->m_CoordUnit; + param->m_pPoints[param->m_PointCount + 2].m_Flag = FXPT_BEZIERTO; + param->m_CurX = to->x; + param->m_CurY = to->y; + } + param->m_PointCount += 3; + return 0; +} }; -CFX_PathData* CFX_Font::LoadGlyphPath(FX_DWORD glyph_index, int dest_width) -{ - if (m_Face == NULL) { - return NULL; - } - FXFT_Set_Pixel_Sizes(m_Face, 0, 64); - FXFT_Matrix ft_matrix = {65536, 0, 0, 65536}; - if (m_pSubstFont) { - if (m_pSubstFont->m_ItalicAngle) { - int skew = m_pSubstFont->m_ItalicAngle; - skew = skew <= -ANGLESKEW_ARRAY_SIZE ? -58 : -g_AngleSkew[-skew]; - if (m_bVertical) { - ft_matrix.yx += ft_matrix.yy * skew / 100; - } else { - ft_matrix.xy += -ft_matrix.xx * skew / 100; - } - } - if (m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) { - AdjustMMParams(glyph_index, dest_width, m_pSubstFont->m_Weight); - } - } - ScopedFontTransform scoped_transform(m_Face, &ft_matrix); - int load_flags = FXFT_LOAD_NO_BITMAP; - if (!(m_Face->face_flags & FT_FACE_FLAG_SFNT) || !FT_IS_TRICKY(m_Face)) { - load_flags |= FT_LOAD_NO_HINTING; - } - int error = FXFT_Load_Glyph(m_Face, glyph_index, load_flags); - if (error) { - return NULL; - } - if (m_pSubstFont && !(m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) && m_pSubstFont->m_Weight > 400) { - int index = (m_pSubstFont->m_Weight - 400) / 10; - if (index >= WEIGHTPOW_ARRAY_SIZE) - index = WEIGHTPOW_ARRAY_SIZE - 1; - int level = 0; - if (m_pSubstFont->m_Charset == FXFONT_SHIFTJIS_CHARSET) { - level = g_WeightPow_SHIFTJIS[index] * 2 * 65536 / 36655; - } else { - level = g_WeightPow[index] * 2; - } - FXFT_Outline_Embolden(FXFT_Get_Glyph_Outline(m_Face), level); - } - FXFT_Outline_Funcs funcs; - funcs.move_to = _Outline_MoveTo; - funcs.line_to = _Outline_LineTo; - funcs.conic_to = _Outline_ConicTo; - funcs.cubic_to = _Outline_CubicTo; - funcs.shift = 0; - funcs.delta = 0; - OUTLINE_PARAMS params; - params.m_bCount = TRUE; - params.m_PointCount = 0; - FXFT_Outline_Decompose(FXFT_Get_Glyph_Outline(m_Face), &funcs, ¶ms); - if (params.m_PointCount == 0) { - return NULL; - } - CFX_PathData* pPath = new CFX_PathData; - pPath->SetPointCount(params.m_PointCount); - params.m_bCount = FALSE; - params.m_PointCount = 0; - params.m_pPoints = pPath->GetPoints(); - params.m_CurX = params.m_CurY = 0; - params.m_CoordUnit = 64 * 64.0; - FXFT_Outline_Decompose(FXFT_Get_Glyph_Outline(m_Face), &funcs, ¶ms); - _Outline_CheckEmptyContour(¶ms); - pPath->TrimPoints(params.m_PointCount); - if (params.m_PointCount) { - pPath->GetPoints()[params.m_PointCount - 1].m_Flag |= FXPT_CLOSEFIGURE; - } - return pPath; +CFX_PathData* CFX_Font::LoadGlyphPath(FX_DWORD glyph_index, int dest_width) { + if (m_Face == NULL) { + return NULL; + } + FXFT_Set_Pixel_Sizes(m_Face, 0, 64); + FXFT_Matrix ft_matrix = {65536, 0, 0, 65536}; + if (m_pSubstFont) { + if (m_pSubstFont->m_ItalicAngle) { + int skew = m_pSubstFont->m_ItalicAngle; + skew = skew <= -ANGLESKEW_ARRAY_SIZE ? -58 : -g_AngleSkew[-skew]; + if (m_bVertical) { + ft_matrix.yx += ft_matrix.yy * skew / 100; + } else { + ft_matrix.xy += -ft_matrix.xx * skew / 100; + } + } + if (m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) { + AdjustMMParams(glyph_index, dest_width, m_pSubstFont->m_Weight); + } + } + ScopedFontTransform scoped_transform(m_Face, &ft_matrix); + int load_flags = FXFT_LOAD_NO_BITMAP; + if (!(m_Face->face_flags & FT_FACE_FLAG_SFNT) || !FT_IS_TRICKY(m_Face)) { + load_flags |= FT_LOAD_NO_HINTING; + } + int error = FXFT_Load_Glyph(m_Face, glyph_index, load_flags); + if (error) { + return NULL; + } + if (m_pSubstFont && !(m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) && + m_pSubstFont->m_Weight > 400) { + int index = (m_pSubstFont->m_Weight - 400) / 10; + if (index >= WEIGHTPOW_ARRAY_SIZE) + index = WEIGHTPOW_ARRAY_SIZE - 1; + int level = 0; + if (m_pSubstFont->m_Charset == FXFONT_SHIFTJIS_CHARSET) { + level = g_WeightPow_SHIFTJIS[index] * 2 * 65536 / 36655; + } else { + level = g_WeightPow[index] * 2; + } + FXFT_Outline_Embolden(FXFT_Get_Glyph_Outline(m_Face), level); + } + FXFT_Outline_Funcs funcs; + funcs.move_to = _Outline_MoveTo; + funcs.line_to = _Outline_LineTo; + funcs.conic_to = _Outline_ConicTo; + funcs.cubic_to = _Outline_CubicTo; + funcs.shift = 0; + funcs.delta = 0; + OUTLINE_PARAMS params; + params.m_bCount = TRUE; + params.m_PointCount = 0; + FXFT_Outline_Decompose(FXFT_Get_Glyph_Outline(m_Face), &funcs, ¶ms); + if (params.m_PointCount == 0) { + return NULL; + } + CFX_PathData* pPath = new CFX_PathData; + pPath->SetPointCount(params.m_PointCount); + params.m_bCount = FALSE; + params.m_PointCount = 0; + params.m_pPoints = pPath->GetPoints(); + params.m_CurX = params.m_CurY = 0; + params.m_CoordUnit = 64 * 64.0; + FXFT_Outline_Decompose(FXFT_Get_Glyph_Outline(m_Face), &funcs, ¶ms); + _Outline_CheckEmptyContour(¶ms); + pPath->TrimPoints(params.m_PointCount); + if (params.m_PointCount) { + pPath->GetPoints()[params.m_PointCount - 1].m_Flag |= FXPT_CLOSEFIGURE; + } + return pPath; } -void _CFX_UniqueKeyGen::Generate(int count, ...) -{ - va_list argList; - va_start(argList, count); - for (int i = 0; i < count; i ++) { - int p = va_arg(argList, int); - ((FX_DWORD*)m_Key)[i] = p; - } - va_end(argList); - m_KeyLen = count * sizeof(FX_DWORD); +void _CFX_UniqueKeyGen::Generate(int count, ...) { + va_list argList; + va_start(argList, count); + for (int i = 0; i < count; i++) { + int p = va_arg(argList, int); + ((FX_DWORD*)m_Key)[i] = p; + } + va_end(argList); + m_KeyLen = count * sizeof(FX_DWORD); } diff --git a/core/src/fxge/ge/text_int.h b/core/src/fxge/ge/text_int.h index 12fac6a60a..a05907162c 100644 --- a/core/src/fxge/ge/text_int.h +++ b/core/src/fxge/ge/text_int.h @@ -8,98 +8,86 @@ #define CORE_SRC_FXGE_GE_TEXT_INT_H_ struct _CFX_UniqueKeyGen { - void Generate(int count, ...); - FX_CHAR m_Key[128]; - int m_KeyLen; + void Generate(int count, ...); + FX_CHAR m_Key[128]; + int m_KeyLen; }; -class CFX_SizeGlyphCache -{ -public: - CFX_SizeGlyphCache() - { - m_GlyphMap.InitHashTable(253); - } - ~CFX_SizeGlyphCache(); - CFX_MapPtrToPtr m_GlyphMap; +class CFX_SizeGlyphCache { + public: + CFX_SizeGlyphCache() { m_GlyphMap.InitHashTable(253); } + ~CFX_SizeGlyphCache(); + CFX_MapPtrToPtr m_GlyphMap; }; -class CTTFontDesc -{ -public: - CTTFontDesc() - { - m_Type = 0; - m_pFontData = NULL; - m_RefCount = 0; - } - ~CTTFontDesc(); - FX_BOOL ReleaseFace(FXFT_Face face); - int m_Type; - union { - struct { - FX_BOOL m_bItalic; - FX_BOOL m_bBold; - FXFT_Face m_pFace; - } m_SingleFace; - struct { - FXFT_Face m_pFaces[16]; - } m_TTCFace; - }; - uint8_t* m_pFontData; - int m_RefCount; +class CTTFontDesc { + public: + CTTFontDesc() { + m_Type = 0; + m_pFontData = NULL; + m_RefCount = 0; + } + ~CTTFontDesc(); + FX_BOOL ReleaseFace(FXFT_Face face); + int m_Type; + union { + struct { + FX_BOOL m_bItalic; + FX_BOOL m_bBold; + FXFT_Face m_pFace; + } m_SingleFace; + struct { + FXFT_Face m_pFaces[16]; + } m_TTCFace; + }; + uint8_t* m_pFontData; + int m_RefCount; }; -class CFX_UnicodeEncoding : public IFX_FontEncoding -{ -public: - CFX_UnicodeEncoding(CFX_Font* pFont); - virtual FX_DWORD GlyphFromCharCodeEx(FX_DWORD charcode, int encoding = ENCODING_UNICODE); -private: - CFX_Font* m_pFont; - virtual FX_DWORD GlyphFromCharCode(FX_DWORD charcode); - virtual CFX_WideString UnicodeFromCharCode(FX_DWORD charcode) const - { - return CFX_WideString((FX_WCHAR)charcode); - } - virtual FX_DWORD CharCodeFromUnicode(FX_WCHAR Unicode) const - { - return Unicode; - } - virtual FX_BOOL IsUnicodeCompatible() const - { - return TRUE; - } +class CFX_UnicodeEncoding : public IFX_FontEncoding { + public: + CFX_UnicodeEncoding(CFX_Font* pFont); + virtual FX_DWORD GlyphFromCharCodeEx(FX_DWORD charcode, + int encoding = ENCODING_UNICODE); + + private: + CFX_Font* m_pFont; + virtual FX_DWORD GlyphFromCharCode(FX_DWORD charcode); + virtual CFX_WideString UnicodeFromCharCode(FX_DWORD charcode) const { + return CFX_WideString((FX_WCHAR)charcode); + } + virtual FX_DWORD CharCodeFromUnicode(FX_WCHAR Unicode) const { + return Unicode; + } + virtual FX_BOOL IsUnicodeCompatible() const { return TRUE; } }; -#define CHARSET_FLAG_ANSI 1 -#define CHARSET_FLAG_SYMBOL 2 -#define CHARSET_FLAG_SHIFTJIS 4 -#define CHARSET_FLAG_BIG5 8 -#define CHARSET_FLAG_GB 16 -#define CHARSET_FLAG_KOREAN 32 -class CFontFaceInfo -{ -public: - CFX_ByteString m_FilePath; - CFX_ByteString m_FaceName; - FX_DWORD m_Styles; - FX_DWORD m_Charsets; - FX_DWORD m_FontOffset; - FX_DWORD m_FileSize; - CFX_ByteString m_FontTables; +#define CHARSET_FLAG_ANSI 1 +#define CHARSET_FLAG_SYMBOL 2 +#define CHARSET_FLAG_SHIFTJIS 4 +#define CHARSET_FLAG_BIG5 8 +#define CHARSET_FLAG_GB 16 +#define CHARSET_FLAG_KOREAN 32 +class CFontFaceInfo { + public: + CFX_ByteString m_FilePath; + CFX_ByteString m_FaceName; + FX_DWORD m_Styles; + FX_DWORD m_Charsets; + FX_DWORD m_FontOffset; + FX_DWORD m_FileSize; + CFX_ByteString m_FontTables; }; -class CFontFileFaceInfo -{ -public: - CFontFileFaceInfo(); - ~CFontFileFaceInfo(); - IFX_FileStream* m_pFile; - FXFT_Face m_Face; - CFX_ByteString m_FaceName; - FX_DWORD m_Charsets; - FX_DWORD m_FileSize; - FX_DWORD m_FontOffset; - int m_Weight; - FX_BOOL m_bItalic; - int m_PitchFamily; - CFX_ByteString m_FontTables; +class CFontFileFaceInfo { + public: + CFontFileFaceInfo(); + ~CFontFileFaceInfo(); + IFX_FileStream* m_pFile; + FXFT_Face m_Face; + CFX_ByteString m_FaceName; + FX_DWORD m_Charsets; + FX_DWORD m_FileSize; + FX_DWORD m_FontOffset; + int m_Weight; + FX_BOOL m_bItalic; + int m_PitchFamily; + CFX_ByteString m_FontTables; }; #endif // CORE_SRC_FXGE_GE_TEXT_INT_H_ diff --git a/core/src/fxge/skia/fx_skia_blitter_new.cpp b/core/src/fxge/skia/fx_skia_blitter_new.cpp index 3437eb497d..a3ed75b9cb 100644 --- a/core/src/fxge/skia/fx_skia_blitter_new.cpp +++ b/core/src/fxge/skia/fx_skia_blitter_new.cpp @@ -8,308 +8,385 @@ #include "../../../include/fxcodec/fx_codec.h" #include "SkBlitter.h" #include "fx_skia_blitter_new.h" - // We use our own renderer here to make it simple - void CFX_SkiaRenderer::blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]) - { - FXSYS_assert(m_Alpha); - if (m_pOriDevice == NULL && composite_span == NULL) return; - if (y < m_ClipBox.top || y >= m_ClipBox.bottom) return; - while (1) - { - int width = runs[0]; - SkASSERT(width >= 0); - if (width <= 0) - return; - unsigned aa = antialias[0]; - if (aa) - (*composite_span)(m_pDestScan, m_pOriScan, 0, x, width, y, aa, m_ClipBox.top, m_ClipBox.left, m_ClipBox.right, m_pClipScan, m_pDestExtraAlphaScan); - runs += width; - antialias += width; - x += width; - } - } +// We use our own renderer here to make it simple +void CFX_SkiaRenderer::blitAntiH(int x, + int y, + const SkAlpha antialias[], + const int16_t runs[]) { + FXSYS_assert(m_Alpha); + if (m_pOriDevice == NULL && composite_span == NULL) + return; + if (y < m_ClipBox.top || y >= m_ClipBox.bottom) + return; + while (1) { + int width = runs[0]; + SkASSERT(width >= 0); + if (width <= 0) + return; + unsigned aa = antialias[0]; + if (aa) + (*composite_span)(m_pDestScan, m_pOriScan, 0, x, width, y, aa, + m_ClipBox.top, m_ClipBox.left, m_ClipBox.right, + m_pClipScan, m_pDestExtraAlphaScan); + runs += width; + antialias += width; + x += width; + } +} - void CFX_SkiaRenderer::blitH(int x, int y, int width) - { - FXSYS_assert(m_Alpha && width); - if (y < m_ClipBox.top || y >= m_ClipBox.bottom) return; - (*composite_span)(m_pDestScan, m_pOriScan, 0, x, width, y, 255, m_ClipBox.top, m_ClipBox.left, m_ClipBox.right, m_pClipScan, m_pDestExtraAlphaScan); - } +void CFX_SkiaRenderer::blitH(int x, int y, int width) { + FXSYS_assert(m_Alpha && width); + if (y < m_ClipBox.top || y >= m_ClipBox.bottom) + return; + (*composite_span)(m_pDestScan, m_pOriScan, 0, x, width, y, 255, m_ClipBox.top, + m_ClipBox.left, m_ClipBox.right, m_pClipScan, + m_pDestExtraAlphaScan); +} - void CFX_SkiaRenderer::blitV(int x, int y, int height, SkAlpha alpha) - { - FXSYS_assert(m_Alpha && alpha); - if (alpha == 255) { - blitRect(x, y, 1, height); - } else { - int16_t runs[2]; - runs[0] = 1; - runs[1] = 0; - while (--height >= 0) { - if (y >= m_ClipBox.bottom) - return; - blitAntiH(x, y ++, &alpha, runs); - } - } - } - void CFX_SkiaRenderer::blitRect(int x, int y, int width, int height) - { - FXSYS_assert(m_Alpha && width); - while (--height >= 0){ - if (y >= m_ClipBox.bottom) - return; - blitH(x, y ++, width); - } +void CFX_SkiaRenderer::blitV(int x, int y, int height, SkAlpha alpha) { + FXSYS_assert(m_Alpha && alpha); + if (alpha == 255) { + blitRect(x, y, 1, height); + } else { + int16_t runs[2]; + runs[0] = 1; + runs[1] = 0; + while (--height >= 0) { + if (y >= m_ClipBox.bottom) + return; + blitAntiH(x, y++, &alpha, runs); } + } +} +void CFX_SkiaRenderer::blitRect(int x, int y, int width, int height) { + FXSYS_assert(m_Alpha && width); + while (--height >= 0) { + if (y >= m_ClipBox.bottom) + return; + blitH(x, y++, width); + } +} - void CFX_SkiaRenderer::blitAntiRect(int x, int y, int width, int height, - SkAlpha leftAlpha, SkAlpha rightAlpha) - { - blitV(x++, y, height, leftAlpha); - if (width > 0) { - blitRect(x, y, width, height); - x += width; - } - blitV(x, y, height, rightAlpha); - } - /*---------------------------------------------------------------------------------------------------*/ - void CFX_SkiaRenderer::CompositeSpan1bpp_0(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan) - { - ASSERT(!m_bRgbByteOrder); - ASSERT(!m_pDevice->IsCmykImage()); - dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + span_left/8; - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - if (col_end < col_start) return; // do nothing. - dest_scan += col_start/8; +void CFX_SkiaRenderer::blitAntiRect(int x, + int y, + int width, + int height, + SkAlpha leftAlpha, + SkAlpha rightAlpha) { + blitV(x++, y, height, leftAlpha); + if (width > 0) { + blitRect(x, y, width, height); + x += width; + } + blitV(x, y, height, rightAlpha); +} +/*---------------------------------------------------------------------------------------------------*/ +void CFX_SkiaRenderer::CompositeSpan1bpp_0(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan) { + ASSERT(!m_bRgbByteOrder); + ASSERT(!m_pDevice->IsCmykImage()); + dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + span_left / 8; + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = + (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); + if (col_end < col_start) + return; // do nothing. + dest_scan += col_start / 8; - int index = 0; - if (m_pDevice->GetPalette() == NULL) - index = ((uint8_t)m_Color == 0xff) ? 1 : 0; - else { - for (int i = 0; i < 2; i ++) - if (FXARGB_TODIB(m_pDevice->GetPalette()[i]) == m_Color) - index = i; - } - uint8_t* dest_scan1 = dest_scan; - int src_alpha = m_Alpha * cover_scan / 255; - for (int col = col_start; col < col_end; col ++) { - if (src_alpha) { - if (!index) - *dest_scan1 &= ~(1 << (7 - (col+span_left)%8)); - else - *dest_scan1|= 1 << (7 - (col+span_left)%8); - } - dest_scan1 = dest_scan+(span_left%8+col-col_start+1)/8; - } + int index = 0; + if (m_pDevice->GetPalette() == NULL) + index = ((uint8_t)m_Color == 0xff) ? 1 : 0; + else { + for (int i = 0; i < 2; i++) + if (FXARGB_TODIB(m_pDevice->GetPalette()[i]) == m_Color) + index = i; + } + uint8_t* dest_scan1 = dest_scan; + int src_alpha = m_Alpha * cover_scan / 255; + for (int col = col_start; col < col_end; col++) { + if (src_alpha) { + if (!index) + *dest_scan1 &= ~(1 << (7 - (col + span_left) % 8)); + else + *dest_scan1 |= 1 << (7 - (col + span_left) % 8); } - void CFX_SkiaRenderer::CompositeSpan1bpp_4(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan) - { - ASSERT(!m_bRgbByteOrder); - ASSERT(!m_pDevice->IsCmykImage()); - dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + span_left/8; - clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top-clip_top) - clip_left + span_left; - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - if (col_end < col_start) return; // do nothing. - dest_scan += col_start/8; + dest_scan1 = dest_scan + (span_left % 8 + col - col_start + 1) / 8; + } +} +void CFX_SkiaRenderer::CompositeSpan1bpp_4(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan) { + ASSERT(!m_bRgbByteOrder); + ASSERT(!m_pDevice->IsCmykImage()); + dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + span_left / 8; + clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top - clip_top) - + clip_left + span_left; + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = + (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); + if (col_end < col_start) + return; // do nothing. + dest_scan += col_start / 8; - int index = 0; - if (m_pDevice->GetPalette() == NULL) - index = ((uint8_t)m_Color == 0xff) ? 1 : 0; - else { - for (int i = 0; i < 2; i ++) - if (FXARGB_TODIB(m_pDevice->GetPalette()[i]) == m_Color) - index = i; - } - uint8_t* dest_scan1 = dest_scan; - int src_alpha = m_Alpha * cover_scan / 255; - for (int col = col_start; col < col_end; col ++) { - int src_alpha1 = src_alpha * clip_scan[col] / 255; - if (src_alpha1) { - if (!index) - *dest_scan1 &= ~(1 << (7 - (col+span_left)%8)); - else - *dest_scan1|= 1 << (7 - (col+span_left)%8); - } - dest_scan1 = dest_scan+(span_left%8+col-col_start+1)/8; - } - } - /*-----------------------------------------------------------------------------------------------------*/ - void CFX_SkiaRenderer::CompositeSpanGray_2(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan) - { - ASSERT(!m_pDevice->IsCmykImage()); - ASSERT(!m_bRgbByteOrder); - dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + span_left; - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - if (col_end < col_start) return; // do nothing. - dest_scan += col_start; - if (cover_scan == 255 && m_Alpha == 255) { - FXSYS_memset(dest_scan, FXARGB_MAKE(m_Gray, m_Gray, m_Gray, m_Gray), col_end - col_start); - return; - } - int src_alpha = m_Alpha * cover_scan / 255; - for (int col = col_start; col < col_end; col ++) { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, src_alpha); - dest_scan++; - } + int index = 0; + if (m_pDevice->GetPalette() == NULL) + index = ((uint8_t)m_Color == 0xff) ? 1 : 0; + else { + for (int i = 0; i < 2; i++) + if (FXARGB_TODIB(m_pDevice->GetPalette()[i]) == m_Color) + index = i; + } + uint8_t* dest_scan1 = dest_scan; + int src_alpha = m_Alpha * cover_scan / 255; + for (int col = col_start; col < col_end; col++) { + int src_alpha1 = src_alpha * clip_scan[col] / 255; + if (src_alpha1) { + if (!index) + *dest_scan1 &= ~(1 << (7 - (col + span_left) % 8)); + else + *dest_scan1 |= 1 << (7 - (col + span_left) % 8); } - void CFX_SkiaRenderer::CompositeSpanGray_3(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan) - { - ASSERT(!m_pDevice->IsCmykImage()); - ASSERT(!m_bRgbByteOrder); - dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + span_left; - ori_scan = (uint8_t*)m_pOriDevice->GetScanline(span_top) + span_left; - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - if (col_end < col_start) return; // do nothing. - dest_scan += col_start; - ori_scan += col_start; - if (m_Alpha == 255 && cover_scan == 255) { - FXSYS_memset(dest_scan, FXARGB_MAKE(m_Gray, m_Gray, m_Gray, m_Gray), col_end - col_start); - } else { - int src_alpha = m_Alpha; + dest_scan1 = dest_scan + (span_left % 8 + col - col_start + 1) / 8; + } +} +/*-----------------------------------------------------------------------------------------------------*/ +void CFX_SkiaRenderer::CompositeSpanGray_2(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan) { + ASSERT(!m_pDevice->IsCmykImage()); + ASSERT(!m_bRgbByteOrder); + dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + span_left; + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = + (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); + if (col_end < col_start) + return; // do nothing. + dest_scan += col_start; + if (cover_scan == 255 && m_Alpha == 255) { + FXSYS_memset(dest_scan, FXARGB_MAKE(m_Gray, m_Gray, m_Gray, m_Gray), + col_end - col_start); + return; + } + int src_alpha = m_Alpha * cover_scan / 255; + for (int col = col_start; col < col_end; col++) { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, src_alpha); + dest_scan++; + } +} +void CFX_SkiaRenderer::CompositeSpanGray_3(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan) { + ASSERT(!m_pDevice->IsCmykImage()); + ASSERT(!m_bRgbByteOrder); + dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + span_left; + ori_scan = (uint8_t*)m_pOriDevice->GetScanline(span_top) + span_left; + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = + (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); + if (col_end < col_start) + return; // do nothing. + dest_scan += col_start; + ori_scan += col_start; + if (m_Alpha == 255 && cover_scan == 255) { + FXSYS_memset(dest_scan, FXARGB_MAKE(m_Gray, m_Gray, m_Gray, m_Gray), + col_end - col_start); + } else { + int src_alpha = m_Alpha; #if 1 - for (int col = col_start; col < col_end; col ++) { - int gray = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, cover_scan); - dest_scan ++; - } + for (int col = col_start; col < col_end; col++) { + int gray = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, cover_scan); + dest_scan++; + } #else - if (m_bFullCover) { - if (src_alpha == 255) { - FXSYS_memset(dest_scan, FXARGB_MAKE(m_Gray, m_Gray, m_Gray, m_Gray), col_end - col_start); - return; - } - for (int col = col_start; col < col_end; col ++) - *dest_scan = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha); - } else { - for (int col = col_start; col < col_end; col ++) { - int gray = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, cover_scan); - dest_scan++; - } - } -#endif - } + if (m_bFullCover) { + if (src_alpha == 255) { + FXSYS_memset(dest_scan, FXARGB_MAKE(m_Gray, m_Gray, m_Gray, m_Gray), + col_end - col_start); + return; + } + for (int col = col_start; col < col_end; col++) + *dest_scan = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha); + } else { + for (int col = col_start; col < col_end; col++) { + int gray = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, cover_scan); + dest_scan++; + } } +#endif + } +} - void CFX_SkiaRenderer::CompositeSpanGray_6(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan) - { - ASSERT(!m_bRgbByteOrder); - dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + span_left; - clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top-clip_top) - clip_left + span_left; - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - if (col_end < col_start) return; // do nothing. - dest_scan += col_start; - int src_alpha = m_Alpha * cover_scan / 255; - for (int col = col_start; col < col_end; col ++) { - int src_alpha1 = src_alpha * clip_scan[col] / 255; - if (!src_alpha1) { - dest_scan ++; - continue; - } - if (src_alpha1 == 255) - *dest_scan++ = m_Gray; - else { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, src_alpha1); - dest_scan ++; - } - } +void CFX_SkiaRenderer::CompositeSpanGray_6(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan) { + ASSERT(!m_bRgbByteOrder); + dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + span_left; + clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top - clip_top) - + clip_left + span_left; + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = + (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); + if (col_end < col_start) + return; // do nothing. + dest_scan += col_start; + int src_alpha = m_Alpha * cover_scan / 255; + for (int col = col_start; col < col_end; col++) { + int src_alpha1 = src_alpha * clip_scan[col] / 255; + if (!src_alpha1) { + dest_scan++; + continue; + } + if (src_alpha1 == 255) + *dest_scan++ = m_Gray; + else { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, src_alpha1); + dest_scan++; } + } +} - void CFX_SkiaRenderer::CompositeSpanGray_7(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan) - { - ASSERT(!m_pDevice->IsCmykImage()); - dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + span_left; - ori_scan = (uint8_t*)m_pOriDevice->GetScanline(span_top) + span_left; - clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top-clip_top) - clip_left + span_left; - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - if (col_end < col_start) return; // do nothing. - dest_scan += col_start; - ori_scan += col_start; +void CFX_SkiaRenderer::CompositeSpanGray_7(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan) { + ASSERT(!m_pDevice->IsCmykImage()); + dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + span_left; + ori_scan = (uint8_t*)m_pOriDevice->GetScanline(span_top) + span_left; + clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top - clip_top) - + clip_left + span_left; + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = + (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); + if (col_end < col_start) + return; // do nothing. + dest_scan += col_start; + ori_scan += col_start; #if 1 - for (int col = col_start; col < col_end; col ++) { - int src_alpha = m_Alpha * clip_scan[col] / 255; - if (src_alpha == 255 && cover_scan == 255) { - *dest_scan++ = m_Gray; - ori_scan++; - continue; - } - int gray = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, cover_scan); - dest_scan++; - } + for (int col = col_start; col < col_end; col++) { + int src_alpha = m_Alpha * clip_scan[col] / 255; + if (src_alpha == 255 && cover_scan == 255) { + *dest_scan++ = m_Gray; + ori_scan++; + continue; + } + int gray = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, cover_scan); + dest_scan++; + } #else - if (m_bFullCover) { - for (int col = col_start; col < col_end; col ++) { - int src_alpha = m_Alpha * clip_scan[col] / 255; - if (!src_alpha) { - dest_scan++; - ori_scan++; - continue; - } - if (src_alpha == 255){ - *dest_scan++ = m_Gray; - ori_scan++; - continue; - } - *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha); - } - } else { - for (int col = col_start; col < col_end; col ++) { - int src_alpha = m_Alpha * clip_scan[col] / 255; - if (src_alpha == 255 && cover_scan == 255) { - *dest_scan++ = m_Gray; - ori_scan++; - continue; - } - int gray = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, cover_scan); - dest_scan++; - } - } -#endif + if (m_bFullCover) { + for (int col = col_start; col < col_end; col++) { + int src_alpha = m_Alpha * clip_scan[col] / 255; + if (!src_alpha) { + dest_scan++; + ori_scan++; + continue; + } + if (src_alpha == 255) { + *dest_scan++ = m_Gray; + ori_scan++; + continue; + } + *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha); } - /*--------------------------------------------------------------------------------------------------*/ + } else { + for (int col = col_start; col < col_end; col++) { + int src_alpha = m_Alpha * clip_scan[col] / 255; + if (src_alpha == 255 && cover_scan == 255) { + *dest_scan++ = m_Gray; + ori_scan++; + continue; + } + int gray = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, cover_scan); + dest_scan++; + } + } +#endif +} +/*--------------------------------------------------------------------------------------------------*/ - void CFX_SkiaRenderer::CompositeSpanARGB_2(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan) - { - dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + (span_left<<2); - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - if (col_end < col_start) return; // do nothing. - dest_scan += col_start<<2; - if (m_Alpha == 255 && cover_scan == 255) { - FXSYS_memset(dest_scan, m_Color, (col_end - col_start)<<2); - return; - } - int src_alpha; +void CFX_SkiaRenderer::CompositeSpanARGB_2(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan) { + dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + (span_left << 2); + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = + (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); + if (col_end < col_start) + return; // do nothing. + dest_scan += col_start << 2; + if (m_Alpha == 255 && cover_scan == 255) { + FXSYS_memset(dest_scan, m_Color, (col_end - col_start) << 2); + return; + } + int src_alpha; #if 0 if (m_bFullCover) { if (m_Alpha == 255) { @@ -319,293 +396,341 @@ } else #endif - src_alpha = m_Alpha * cover_scan / 255; - for (int col = col_start; col < col_end; col ++) { - // Dest format: Argb - // calculate destination alpha (it's union of source and dest alpha) - if (dest_scan[3] == 0) { - dest_scan[3] = src_alpha; - *dest_scan++ = m_Blue; - *dest_scan++ = m_Green; - *dest_scan = m_Red; - dest_scan += 2; - continue; - } - uint8_t dest_alpha = dest_scan[3] + src_alpha - dest_scan[3] * src_alpha / 255; - dest_scan[3] = dest_alpha; - int alpha_ratio = src_alpha*255/dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); - dest_scan += 2; - } + src_alpha = m_Alpha * cover_scan / 255; + for (int col = col_start; col < col_end; col++) { + // Dest format: Argb + // calculate destination alpha (it's union of source and dest alpha) + if (dest_scan[3] == 0) { + dest_scan[3] = src_alpha; + *dest_scan++ = m_Blue; + *dest_scan++ = m_Green; + *dest_scan = m_Red; + dest_scan += 2; + continue; } + uint8_t dest_alpha = + dest_scan[3] + src_alpha - dest_scan[3] * src_alpha / 255; + dest_scan[3] = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); + dest_scan += 2; + } +} - void CFX_SkiaRenderer::CompositeSpanARGB_3(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan) - { - ASSERT(!m_pDevice->IsCmykImage()); - dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + (span_left<<2); - //ori_scan = (uint8_t*)m_pOriDevice->GetScanline(span_top) + (span_left<<2); - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - if (col_end < col_start) return; // do nothing. - dest_scan += col_start << 2; - //ori_scan += col_start << 2; +void CFX_SkiaRenderer::CompositeSpanARGB_3(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan) { + ASSERT(!m_pDevice->IsCmykImage()); + dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + (span_left << 2); + // ori_scan = (uint8_t*)m_pOriDevice->GetScanline(span_top) + (span_left<<2); + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = + (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); + if (col_end < col_start) + return; // do nothing. + dest_scan += col_start << 2; + // ori_scan += col_start << 2; - if (m_Alpha == 255 && cover_scan == 255){ - FXSYS_memset(dest_scan, m_Color, (col_end - col_start)<<2); - return; - } - if (cover_scan == 255) { - int dst_color = (0x00ffffff&m_Color)|(m_Alpha<<24); - FXSYS_memset(dest_scan, dst_color, (col_end - col_start)<<2); - return; - } - // Do not need origin bitmap, because of merge in pure transparent background - int src_alpha_covered = m_Alpha * cover_scan / 255; - for (int col = col_start; col < col_end; col ++) - { - // shortcut - if (dest_scan[3] == 0) { - dest_scan[3] = src_alpha_covered; - *dest_scan ++ = m_Blue; - *dest_scan ++ = m_Green; - *dest_scan = m_Red; - dest_scan += 2; - continue; - } - // We should do alpha transition and color transition - // alpha fg color fg - // alpha bg color bg - // alpha cover color cover - dest_scan[3] = FXDIB_ALPHA_MERGE(dest_scan[3], m_Alpha, cover_scan); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, cover_scan); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, cover_scan); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, cover_scan); - dest_scan += 2; - } + if (m_Alpha == 255 && cover_scan == 255) { + FXSYS_memset(dest_scan, m_Color, (col_end - col_start) << 2); + return; + } + if (cover_scan == 255) { + int dst_color = (0x00ffffff & m_Color) | (m_Alpha << 24); + FXSYS_memset(dest_scan, dst_color, (col_end - col_start) << 2); + return; + } + // Do not need origin bitmap, because of merge in pure transparent background + int src_alpha_covered = m_Alpha * cover_scan / 255; + for (int col = col_start; col < col_end; col++) { + // shortcut + if (dest_scan[3] == 0) { + dest_scan[3] = src_alpha_covered; + *dest_scan++ = m_Blue; + *dest_scan++ = m_Green; + *dest_scan = m_Red; + dest_scan += 2; + continue; } - void CFX_SkiaRenderer::CompositeSpanARGB_6(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan) - { - dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + (span_left<<2); - clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top-clip_top) - clip_left + span_left; - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - if (col_end < col_start) return; // do nothing. - dest_scan += col_start << 2; + // We should do alpha transition and color transition + // alpha fg color fg + // alpha bg color bg + // alpha cover color cover + dest_scan[3] = FXDIB_ALPHA_MERGE(dest_scan[3], m_Alpha, cover_scan); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, cover_scan); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, cover_scan); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, cover_scan); + dest_scan += 2; + } +} +void CFX_SkiaRenderer::CompositeSpanARGB_6(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan) { + dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + (span_left << 2); + clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top - clip_top) - + clip_left + span_left; + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = + (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); + if (col_end < col_start) + return; // do nothing. + dest_scan += col_start << 2; #if 1 - int src_alpha = m_Alpha * cover_scan / 255; - for (int col = col_start; col < col_end; col ++) { - int src_alpha1 = src_alpha* clip_scan[col] / 255; - if (!src_alpha1) { - dest_scan += 4; - continue; - } - if (src_alpha1 == 255) { - *(FX_DWORD*)dest_scan = m_Color; - dest_scan += 4; - } else { - // Dest format: Argb - // calculate destination alpha (it's union of source and dest alpha) - if (dest_scan[3] == 0) { - dest_scan[3] = src_alpha1; - *dest_scan++ = m_Blue; - *dest_scan++ = m_Green; - *dest_scan = m_Red; - dest_scan += 2; - continue; - } - uint8_t dest_alpha = dest_scan[3] + src_alpha1 - dest_scan[3] * src_alpha1 / 255; - dest_scan[3] = dest_alpha; - int alpha_ratio = src_alpha1*255/dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); - dest_scan += 2; - } - } + int src_alpha = m_Alpha * cover_scan / 255; + for (int col = col_start; col < col_end; col++) { + int src_alpha1 = src_alpha * clip_scan[col] / 255; + if (!src_alpha1) { + dest_scan += 4; + continue; + } + if (src_alpha1 == 255) { + *(FX_DWORD*)dest_scan = m_Color; + dest_scan += 4; + } else { + // Dest format: Argb + // calculate destination alpha (it's union of source and dest alpha) + if (dest_scan[3] == 0) { + dest_scan[3] = src_alpha1; + *dest_scan++ = m_Blue; + *dest_scan++ = m_Green; + *dest_scan = m_Red; + dest_scan += 2; + continue; + } + uint8_t dest_alpha = + dest_scan[3] + src_alpha1 - dest_scan[3] * src_alpha1 / 255; + dest_scan[3] = dest_alpha; + int alpha_ratio = src_alpha1 * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); + dest_scan += 2; + } + } #else - if (m_bFullCover) { - for (int col = col_start; col < col_end; col ++) { - int src_alpha = m_Alpha * clip_scan[col] / 255; - if (!src_alpha) { - dest_scan += 4; - continue; - } - if (src_alpha == 255){ - *(FX_DWORD*)dest_scan = m_Color; - dest_scan += 4; - continue; - } else { - // Dest format: Argb - // calculate destination alpha (it's union of source and dest alpha) - if (dest_scan[3] == 0) { - dest_scan[3] = src_alpha; - *dest_scan++ = m_Blue; - *dest_scan++ = m_Green; - *dest_scan = m_Red; - dest_scan += 2; - continue; - } - uint8_t dest_alpha = dest_scan[3] + src_alpha - dest_scan[3] * src_alpha / 255; - dest_scan[3] = dest_alpha; - int alpha_ratio = src_alpha*255/dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); - dest_scan += 2; - } - } - } else { - int src_alpha = m_Alpha * cover_scan / 255; - for (int col = col_start; col < col_end; col ++) { - int src_alpha1 = src_alpha* clip_scan[col] / 255; - if (!src_alpha1) { - dest_scan += 4; - continue; - } - if (src_alpha1 == 255) { - *(FX_DWORD*)dest_scan = m_Color; - dest_scan += 4; - } else { - // Dest format: Argb - // calculate destination alpha (it's union of source and dest alpha) - if (dest_scan[3] == 0) { - dest_scan[3] = src_alpha1; - *dest_scan++ = m_Blue; - *dest_scan++ = m_Green; - *dest_scan = m_Red; - dest_scan += 2; - continue; - } - uint8_t dest_alpha = dest_scan[3] + src_alpha1 - dest_scan[3] * src_alpha1 / 255; - dest_scan[3] = dest_alpha; - int alpha_ratio = src_alpha1*255/dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); - dest_scan += 2; - } - } + if (m_bFullCover) { + for (int col = col_start; col < col_end; col++) { + int src_alpha = m_Alpha * clip_scan[col] / 255; + if (!src_alpha) { + dest_scan += 4; + continue; + } + if (src_alpha == 255) { + *(FX_DWORD*)dest_scan = m_Color; + dest_scan += 4; + continue; + } else { + // Dest format: Argb + // calculate destination alpha (it's union of source and dest alpha) + if (dest_scan[3] == 0) { + dest_scan[3] = src_alpha; + *dest_scan++ = m_Blue; + *dest_scan++ = m_Green; + *dest_scan = m_Red; + dest_scan += 2; + continue; } -#endif + uint8_t dest_alpha = + dest_scan[3] + src_alpha - dest_scan[3] * src_alpha / 255; + dest_scan[3] = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); + dest_scan += 2; + } } - - void CFX_SkiaRenderer::CompositeSpanARGB_7(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan) - { - ASSERT(!m_pDevice->IsCmykImage()); - dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + (span_left<<2); - //ori_scan = (uint8_t*)m_pOriDevice->GetScanline(span_top) + (span_left<<2); - clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top-clip_top) - clip_left + span_left; - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - if (col_end < col_start) return; // do nothing. - dest_scan += col_start << 2; - //ori_scan += col_start << 2; - // Do not need origin bitmap, because of merge in pure transparent background - for (int col = col_start; col < col_end; col ++) - { - int src_alpha = m_Alpha * clip_scan[col] / 255; - int src_alpha_covered = src_alpha * cover_scan / 255; - // shortcut - if (src_alpha_covered == 0){ - dest_scan += 4; - continue; - } - // shortcut - if (cover_scan == 255 || dest_scan[3] == 0) - { - // origin alpha always zero, just get src alpha - dest_scan[3] = src_alpha_covered; - *dest_scan ++ = m_Blue; - *dest_scan ++ = m_Green; - *dest_scan = m_Red; - dest_scan += 2; - continue; - } - // We should do alpha transition and color transition - // alpha fg color fg - // alpha bg color bg - // alpha cover color cover - dest_scan[3] = FXDIB_ALPHA_MERGE(dest_scan[3], src_alpha, cover_scan); - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, cover_scan); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, cover_scan); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, cover_scan); - dest_scan += 2; + } else { + int src_alpha = m_Alpha * cover_scan / 255; + for (int col = col_start; col < col_end; col++) { + int src_alpha1 = src_alpha * clip_scan[col] / 255; + if (!src_alpha1) { + dest_scan += 4; + continue; + } + if (src_alpha1 == 255) { + *(FX_DWORD*)dest_scan = m_Color; + dest_scan += 4; + } else { + // Dest format: Argb + // calculate destination alpha (it's union of source and dest alpha) + if (dest_scan[3] == 0) { + dest_scan[3] = src_alpha1; + *dest_scan++ = m_Blue; + *dest_scan++ = m_Green; + *dest_scan = m_Red; + dest_scan += 2; + continue; } + uint8_t dest_alpha = + dest_scan[3] + src_alpha1 - dest_scan[3] * src_alpha1 / 255; + dest_scan[3] = dest_alpha; + int alpha_ratio = src_alpha1 * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); + dest_scan += 2; + } } + } +#endif +} - /*-----------------------------------------------------------------------------------------------------------*/ - void CFX_SkiaRenderer::CompositeSpanRGB32_2(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan) - { - dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + (span_left<<2); - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - if (col_end < col_start) return; // do nothing. - dest_scan += (col_start << 2); - if (m_Alpha == 255 && cover_scan == 255) { - FXSYS_memset(dest_scan, m_Color, (col_end - col_start)<<2); - return; - } - int src_alpha; +void CFX_SkiaRenderer::CompositeSpanARGB_7(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan) { + ASSERT(!m_pDevice->IsCmykImage()); + dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + (span_left << 2); + // ori_scan = (uint8_t*)m_pOriDevice->GetScanline(span_top) + (span_left<<2); + clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top - clip_top) - + clip_left + span_left; + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = + (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); + if (col_end < col_start) + return; // do nothing. + dest_scan += col_start << 2; + // ori_scan += col_start << 2; + // Do not need origin bitmap, because of merge in pure transparent background + for (int col = col_start; col < col_end; col++) { + int src_alpha = m_Alpha * clip_scan[col] / 255; + int src_alpha_covered = src_alpha * cover_scan / 255; + // shortcut + if (src_alpha_covered == 0) { + dest_scan += 4; + continue; + } + // shortcut + if (cover_scan == 255 || dest_scan[3] == 0) { + // origin alpha always zero, just get src alpha + dest_scan[3] = src_alpha_covered; + *dest_scan++ = m_Blue; + *dest_scan++ = m_Green; + *dest_scan = m_Red; + dest_scan += 2; + continue; + } + // We should do alpha transition and color transition + // alpha fg color fg + // alpha bg color bg + // alpha cover color cover + dest_scan[3] = FXDIB_ALPHA_MERGE(dest_scan[3], src_alpha, cover_scan); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, cover_scan); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, cover_scan); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, cover_scan); + dest_scan += 2; + } +} + +/*-----------------------------------------------------------------------------------------------------------*/ +void CFX_SkiaRenderer::CompositeSpanRGB32_2(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan) { + dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + (span_left << 2); + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = + (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); + if (col_end < col_start) + return; // do nothing. + dest_scan += (col_start << 2); + if (m_Alpha == 255 && cover_scan == 255) { + FXSYS_memset(dest_scan, m_Color, (col_end - col_start) << 2); + return; + } + int src_alpha; #if 0 if (m_bFullCover) src_alpha = m_Alpha; else #endif - src_alpha = m_Alpha * cover_scan / 255; - for (int col = col_start; col < col_end; col ++) { - // Dest format: Rgb32 - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha); - dest_scan += 2; - } - } - void CFX_SkiaRenderer::CompositeSpanRGB32_3(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan) - { - dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + (span_left<<2); - ori_scan = (uint8_t*)m_pOriDevice->GetScanline(span_top) + (span_left<<2); - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - if (col_end < col_start) return; // do nothing. - dest_scan += col_start << 2; - ori_scan += col_start << 2; - if (m_Alpha == 255 && cover_scan == 255) { - FXSYS_memset(dest_scan, m_Color, (col_end - col_start)<<2); - return; - } - int src_alpha = m_Alpha; - for (int col = col_start; col < col_end; col ++) { + src_alpha = m_Alpha * cover_scan / 255; + for (int col = col_start; col < col_end; col++) { + // Dest format: Rgb32 + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha); + dest_scan += 2; + } +} +void CFX_SkiaRenderer::CompositeSpanRGB32_3(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan) { + dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + (span_left << 2); + ori_scan = (uint8_t*)m_pOriDevice->GetScanline(span_top) + (span_left << 2); + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = + (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); + if (col_end < col_start) + return; // do nothing. + dest_scan += col_start << 2; + ori_scan += col_start << 2; + if (m_Alpha == 255 && cover_scan == 255) { + FXSYS_memset(dest_scan, m_Color, (col_end - col_start) << 2); + return; + } + int src_alpha = m_Alpha; + for (int col = col_start; col < col_end; col++) { #if 0 if (m_bFullCover) { *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); @@ -615,231 +740,273 @@ continue; } #endif - int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); - int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); - int r = FXDIB_ALPHA_MERGE(*ori_scan, m_Red, src_alpha); - ori_scan += 2; - *dest_scan = FXDIB_ALPHA_MERGE( *dest_scan, b, cover_scan); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan); - dest_scan += 2; - } - } - void CFX_SkiaRenderer::CompositeSpanRGB32_6(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan) - { - dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + (span_left<<2); - clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top-clip_top) - clip_left + span_left; - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - if (col_end < col_start) return; // do nothing. - dest_scan += col_start << 2; + int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); + int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); + int r = FXDIB_ALPHA_MERGE(*ori_scan, m_Red, src_alpha); + ori_scan += 2; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan); + dest_scan += 2; + } +} +void CFX_SkiaRenderer::CompositeSpanRGB32_6(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan) { + dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + (span_left << 2); + clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top - clip_top) - + clip_left + span_left; + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = + (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); + if (col_end < col_start) + return; // do nothing. + dest_scan += col_start << 2; #if 1 - int src_alpha = m_Alpha * cover_scan / 255; - for (int col = col_start; col < col_end; col ++) { - int src_alpha1 = src_alpha * clip_scan[col] / 255; - if (!src_alpha1) { - dest_scan += 4; - continue; - } - if (src_alpha1 == 255) { - *(FX_DWORD*)dest_scan = m_Color; - dest_scan += 4; - } else { - // Dest format: Rgb or Rgb32 - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha1); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha1); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha1); - dest_scan += 2; - } - } + int src_alpha = m_Alpha * cover_scan / 255; + for (int col = col_start; col < col_end; col++) { + int src_alpha1 = src_alpha * clip_scan[col] / 255; + if (!src_alpha1) { + dest_scan += 4; + continue; + } + if (src_alpha1 == 255) { + *(FX_DWORD*)dest_scan = m_Color; + dest_scan += 4; + } else { + // Dest format: Rgb or Rgb32 + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha1); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha1); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha1); + dest_scan += 2; + } + } #else - if (m_bFullCover) { - for (int col = col_start; col < col_end; col ++) { - int src_alpha = m_Alpha * clip_scan[col] / 255; - if (!src_alpha) { - dest_scan += 4; - continue; - } - if (src_alpha == 255) { - *(FX_DWORD*)dest_scan = m_Color; - dest_scan += 4; - } else { - // Dest format: Rgb or Rgb32 - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha); - dest_scan += 2; - } - } - } else { - // Rgb32 - int src_alpha = m_Alpha * cover_scan / 255; - for (int col = col_start; col < col_end; col ++) { - int src_alpha1 = src_alpha * clip_scan[col] / 255; - if (!src_alpha1) { - dest_scan += 4; - continue; - } - if (src_alpha1 == 255) { - *(FX_DWORD*)dest_scan = m_Color; - dest_scan += 4; - } else { - // Dest format: Rgb or Rgb32 - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha1); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha1); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha1); - dest_scan += 2; - } - } - } -#endif + if (m_bFullCover) { + for (int col = col_start; col < col_end; col++) { + int src_alpha = m_Alpha * clip_scan[col] / 255; + if (!src_alpha) { + dest_scan += 4; + continue; + } + if (src_alpha == 255) { + *(FX_DWORD*)dest_scan = m_Color; + dest_scan += 4; + } else { + // Dest format: Rgb or Rgb32 + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha); + dest_scan += 2; + } } - void CFX_SkiaRenderer::CompositeSpanRGB32_7(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan) - { - ASSERT(!m_pDevice->IsCmykImage()); - dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + (span_left<<2); - ori_scan = (uint8_t*)m_pOriDevice->GetScanline(span_top) + (span_left<<2); - clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top-clip_top) - clip_left + span_left; - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - if (col_end < col_start) return; // do nothing. - dest_scan += col_start << 2; - ori_scan += col_start << 2; + } else { + // Rgb32 + int src_alpha = m_Alpha * cover_scan / 255; + for (int col = col_start; col < col_end; col++) { + int src_alpha1 = src_alpha * clip_scan[col] / 255; + if (!src_alpha1) { + dest_scan += 4; + continue; + } + if (src_alpha1 == 255) { + *(FX_DWORD*)dest_scan = m_Color; + dest_scan += 4; + } else { + // Dest format: Rgb or Rgb32 + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha1); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha1); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha1); + dest_scan += 2; + } + } + } +#endif +} +void CFX_SkiaRenderer::CompositeSpanRGB32_7(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan) { + ASSERT(!m_pDevice->IsCmykImage()); + dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + (span_left << 2); + ori_scan = (uint8_t*)m_pOriDevice->GetScanline(span_top) + (span_left << 2); + clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top - clip_top) - + clip_left + span_left; + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = + (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); + if (col_end < col_start) + return; // do nothing. + dest_scan += col_start << 2; + ori_scan += col_start << 2; #if 1 - for (int col = col_start; col < col_end; col ++) { - int src_alpha = m_Alpha * clip_scan[col] / 255; - if (src_alpha == 255 && cover_scan == 255) { - *(FX_DWORD*)dest_scan = m_Color; - dest_scan += 4; - ori_scan += 4; - continue; - } - int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); - int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); - int r = FXDIB_ALPHA_MERGE(*ori_scan, m_Red, src_alpha); - ori_scan += 2; - *dest_scan = FXDIB_ALPHA_MERGE( *dest_scan, b, cover_scan); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan); - dest_scan += 2; - } + for (int col = col_start; col < col_end; col++) { + int src_alpha = m_Alpha * clip_scan[col] / 255; + if (src_alpha == 255 && cover_scan == 255) { + *(FX_DWORD*)dest_scan = m_Color; + dest_scan += 4; + ori_scan += 4; + continue; + } + int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); + int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); + int r = FXDIB_ALPHA_MERGE(*ori_scan, m_Red, src_alpha); + ori_scan += 2; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan); + dest_scan += 2; + } #else - if (m_bFullCover) { - for (int col = col_start; col < col_end; col ++) { - int src_alpha = m_Alpha * clip_scan[col] / 255; - if (!src_alpha) { - *(FX_DWORD*)dest_scan = *(FX_DWORD*)ori_scan; - dest_scan += 4; - ori_scan += 4; - continue; - } - if (src_alpha == 255) { - *(FX_DWORD*)dest_scan = m_Color; - dest_scan += 4; - ori_scan += 4; - continue; - } - *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); - *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); - *dest_scan = FXDIB_ALPHA_MERGE(*ori_scan, m_Red, src_alpha); - dest_scan += 2; ori_scan += 2; - } - } else { - for (int col = col_start; col < col_end; col ++) { - int src_alpha = m_Alpha * clip_scan[col] / 255; - if (src_alpha == 255 && cover_scan == 255) { - *(FX_DWORD*)dest_scan = m_Color; - dest_scan += 4; - ori_scan += 4; - continue; - } - int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); - int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); - int r = FXDIB_ALPHA_MERGE(*ori_scan, m_Red, src_alpha); - ori_scan += 2; - *dest_scan = FXDIB_ALPHA_MERGE( *dest_scan, b, cover_scan); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan); - dest_scan += 2; - } - } -#endif + if (m_bFullCover) { + for (int col = col_start; col < col_end; col++) { + int src_alpha = m_Alpha * clip_scan[col] / 255; + if (!src_alpha) { + *(FX_DWORD*)dest_scan = *(FX_DWORD*)ori_scan; + dest_scan += 4; + ori_scan += 4; + continue; + } + if (src_alpha == 255) { + *(FX_DWORD*)dest_scan = m_Color; + dest_scan += 4; + ori_scan += 4; + continue; + } + *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); + *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); + *dest_scan = FXDIB_ALPHA_MERGE(*ori_scan, m_Red, src_alpha); + dest_scan += 2; + ori_scan += 2; } - /*-----------------------------------------------------------------------------------------------------*/ - void CFX_SkiaRenderer::CompositeSpanRGB24_2(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan) - { - dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + span_left + (span_left<<1); - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - if (col_end < col_start) return; // do nothing. - dest_scan += (col_start<<1)+col_start; - int src_alpha; + } else { + for (int col = col_start; col < col_end; col++) { + int src_alpha = m_Alpha * clip_scan[col] / 255; + if (src_alpha == 255 && cover_scan == 255) { + *(FX_DWORD*)dest_scan = m_Color; + dest_scan += 4; + ori_scan += 4; + continue; + } + int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); + int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); + int r = FXDIB_ALPHA_MERGE(*ori_scan, m_Red, src_alpha); + ori_scan += 2; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan); + dest_scan += 2; + } + } +#endif +} +/*-----------------------------------------------------------------------------------------------------*/ +void CFX_SkiaRenderer::CompositeSpanRGB24_2(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan) { + dest_scan = + (uint8_t*)m_pDevice->GetScanline(span_top) + span_left + (span_left << 1); + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = + (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); + if (col_end < col_start) + return; // do nothing. + dest_scan += (col_start << 1) + col_start; + int src_alpha; #if 0 if (m_bFullCover) src_alpha = m_Alpha; else #endif - src_alpha = m_Alpha * cover_scan / 255; - if (src_alpha == 255) { - for (int col = col_start; col < col_end; col ++) { - *dest_scan++ = m_Blue; - *dest_scan++ = m_Green; - *dest_scan++ = m_Red; - } - return; - } - for (int col = col_start; col < col_end; col ++) { - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha); - dest_scan ++; - } + src_alpha = m_Alpha * cover_scan / 255; + if (src_alpha == 255) { + for (int col = col_start; col < col_end; col++) { + *dest_scan++ = m_Blue; + *dest_scan++ = m_Green; + *dest_scan++ = m_Red; } - void CFX_SkiaRenderer::CompositeSpanRGB24_3(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan) - { - ASSERT(!m_pDevice->IsCmykImage()); - dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + span_left + (span_left<<1); - ori_scan = (uint8_t*)m_pOriDevice->GetScanline(span_top) + span_left + (span_left<<1); - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - if (col_end < col_start) return; // do nothing. - dest_scan += (col_start<<1) + col_start; - ori_scan += (col_start<<1) + col_start; - if (m_Alpha == 255&&cover_scan == 255) { - for (int col = col_start; col < col_end; col ++) { - *dest_scan ++ = m_Blue; - *dest_scan ++ = m_Green; - *dest_scan ++ = m_Red; - } - return; - } - for (int col = col_start; col < col_end; col ++) { + return; + } + for (int col = col_start; col < col_end; col++) { + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha); + dest_scan++; + } +} +void CFX_SkiaRenderer::CompositeSpanRGB24_3(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan) { + ASSERT(!m_pDevice->IsCmykImage()); + dest_scan = + (uint8_t*)m_pDevice->GetScanline(span_top) + span_left + (span_left << 1); + ori_scan = (uint8_t*)m_pOriDevice->GetScanline(span_top) + span_left + + (span_left << 1); + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = + (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); + if (col_end < col_start) + return; // do nothing. + dest_scan += (col_start << 1) + col_start; + ori_scan += (col_start << 1) + col_start; + if (m_Alpha == 255 && cover_scan == 255) { + for (int col = col_start; col < col_end; col++) { + *dest_scan++ = m_Blue; + *dest_scan++ = m_Green; + *dest_scan++ = m_Red; + } + return; + } + for (int col = col_start; col < col_end; col++) { #if 0 if (m_bFullCover) { *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, m_Alpha); @@ -848,762 +1015,834 @@ continue; } #endif - int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, m_Alpha); - int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, m_Alpha); - int r = FXDIB_ALPHA_MERGE(*ori_scan++, m_Red, m_Alpha); - *dest_scan = FXDIB_ALPHA_MERGE( *dest_scan, b, cover_scan); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan); - dest_scan ++; - } - } - void CFX_SkiaRenderer::CompositeSpanRGB24_6(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan) - { - dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + span_left+(span_left<<1); - clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top-clip_top) - clip_left + span_left; - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - if (col_end < col_start) return; // do nothing. - dest_scan += col_start + (col_start << 1); + int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, m_Alpha); + int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, m_Alpha); + int r = FXDIB_ALPHA_MERGE(*ori_scan++, m_Red, m_Alpha); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan); + dest_scan++; + } +} +void CFX_SkiaRenderer::CompositeSpanRGB24_6(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan) { + dest_scan = + (uint8_t*)m_pDevice->GetScanline(span_top) + span_left + (span_left << 1); + clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top - clip_top) - + clip_left + span_left; + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = + (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); + if (col_end < col_start) + return; // do nothing. + dest_scan += col_start + (col_start << 1); #if 1 - int src_alpha = m_Alpha * cover_scan /255; - for (int col = col_start; col < col_end; col ++) { - int src_alpha1 = src_alpha * clip_scan[col] / 255; - if (!src_alpha1) { - dest_scan += 3; - continue; - } - if (src_alpha1 == 255) { - *dest_scan++ = m_Blue; - *dest_scan++ = m_Green; - *dest_scan++ = m_Red; - } else { - // Dest format: Rgb - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha1); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha1); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha1); - dest_scan ++; - } - } + int src_alpha = m_Alpha * cover_scan / 255; + for (int col = col_start; col < col_end; col++) { + int src_alpha1 = src_alpha * clip_scan[col] / 255; + if (!src_alpha1) { + dest_scan += 3; + continue; + } + if (src_alpha1 == 255) { + *dest_scan++ = m_Blue; + *dest_scan++ = m_Green; + *dest_scan++ = m_Red; + } else { + // Dest format: Rgb + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha1); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha1); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha1); + dest_scan++; + } + } #else - if (m_bFullCover) { - for (int col = col_start; col < col_end; col ++) { - int src_alpha = m_Alpha * clip_scan[col] / 255; - if (!src_alpha) { - dest_scan += 3; - continue; - } - if (src_alpha == 255) { - *dest_scan++ = m_Blue; - *dest_scan++ = m_Green; - *dest_scan++ = m_Red; - } else { - // Dest format: Rgb - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha); - dest_scan ++; - } - } - } else { - int src_alpha = m_Alpha * cover_scan /255; - for (int col = col_start; col < col_end; col ++) { - int src_alpha1 = src_alpha * clip_scan[col] / 255; - if (!src_alpha1) { - dest_scan += 3; - continue; - } - if (src_alpha1 == 255) { - *dest_scan++ = m_Blue; - *dest_scan++ = m_Green; - *dest_scan++ = m_Red; - } else { - // Dest format: Rgb - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha1); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha1); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha1); - dest_scan ++; - } - } - } -#endif + if (m_bFullCover) { + for (int col = col_start; col < col_end; col++) { + int src_alpha = m_Alpha * clip_scan[col] / 255; + if (!src_alpha) { + dest_scan += 3; + continue; + } + if (src_alpha == 255) { + *dest_scan++ = m_Blue; + *dest_scan++ = m_Green; + *dest_scan++ = m_Red; + } else { + // Dest format: Rgb + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha); + dest_scan++; + } } - void CFX_SkiaRenderer::CompositeSpanRGB24_7(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan) - { - ASSERT(!m_pDevice->IsCmykImage()); - dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + span_left+(span_left<<1); - ori_scan = (uint8_t*)m_pOriDevice->GetScanline(span_top) + span_left+(span_left<<1); - clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top-clip_top) - clip_left + span_left; - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - if (col_end < col_start) return; // do nothing. - dest_scan += col_start + (col_start<<1); - ori_scan += col_start + (col_start<<1); + } else { + int src_alpha = m_Alpha * cover_scan / 255; + for (int col = col_start; col < col_end; col++) { + int src_alpha1 = src_alpha * clip_scan[col] / 255; + if (!src_alpha1) { + dest_scan += 3; + continue; + } + if (src_alpha1 == 255) { + *dest_scan++ = m_Blue; + *dest_scan++ = m_Green; + *dest_scan++ = m_Red; + } else { + // Dest format: Rgb + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha1); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha1); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha1); + dest_scan++; + } + } + } +#endif +} +void CFX_SkiaRenderer::CompositeSpanRGB24_7(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan) { + ASSERT(!m_pDevice->IsCmykImage()); + dest_scan = + (uint8_t*)m_pDevice->GetScanline(span_top) + span_left + (span_left << 1); + ori_scan = (uint8_t*)m_pOriDevice->GetScanline(span_top) + span_left + + (span_left << 1); + clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top - clip_top) - + clip_left + span_left; + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = + (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); + if (col_end < col_start) + return; // do nothing. + dest_scan += col_start + (col_start << 1); + ori_scan += col_start + (col_start << 1); #if 1 - for (int col = col_start; col < col_end; col ++) { - int src_alpha = m_Alpha * clip_scan[col] / 255; - if (src_alpha == 255 && cover_scan == 255) { - *dest_scan++ = m_Blue; - *dest_scan++ = m_Green; - *dest_scan++ = m_Red; - ori_scan += 3; - continue; - } - int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); - int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); - int r = FXDIB_ALPHA_MERGE(*ori_scan++, m_Red, src_alpha); - *dest_scan = FXDIB_ALPHA_MERGE( *dest_scan, b, cover_scan); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan); - dest_scan ++; - } + for (int col = col_start; col < col_end; col++) { + int src_alpha = m_Alpha * clip_scan[col] / 255; + if (src_alpha == 255 && cover_scan == 255) { + *dest_scan++ = m_Blue; + *dest_scan++ = m_Green; + *dest_scan++ = m_Red; + ori_scan += 3; + continue; + } + int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); + int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); + int r = FXDIB_ALPHA_MERGE(*ori_scan++, m_Red, src_alpha); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan); + dest_scan++; + } #else - if (m_bFullCover) { - for (int col = col_start; col < col_end; col ++) { - int src_alpha = m_Alpha * clip_scan[col] / 255; - if (!src_alpha){ - *dest_scan++ = *ori_scan++; - *dest_scan++ = *ori_scan++; - *dest_scan++ = *ori_scan++; - continue; - } - if (src_alpha == 255){ - *dest_scan++ = m_Blue; - *dest_scan++ = m_Green; - *dest_scan++ = m_Red; - ori_scan += 3; - continue; - } - *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); - *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); - *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Red, src_alpha); - } - } else { - for (int col = col_start; col < col_end; col ++) { - int src_alpha = m_Alpha * clip_scan[col] / 255; - if (src_alpha == 255 && cover_scan == 255) { - *dest_scan++ = m_Blue; - *dest_scan++ = m_Green; - *dest_scan++ = m_Red; - ori_scan += 3; - continue; - } - int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); - int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); - int r = FXDIB_ALPHA_MERGE(*ori_scan++, m_Red, src_alpha); - *dest_scan = FXDIB_ALPHA_MERGE( *dest_scan, b, cover_scan); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan); - dest_scan ++; - } - } -#endif + if (m_bFullCover) { + for (int col = col_start; col < col_end; col++) { + int src_alpha = m_Alpha * clip_scan[col] / 255; + if (!src_alpha) { + *dest_scan++ = *ori_scan++; + *dest_scan++ = *ori_scan++; + *dest_scan++ = *ori_scan++; + continue; + } + if (src_alpha == 255) { + *dest_scan++ = m_Blue; + *dest_scan++ = m_Green; + *dest_scan++ = m_Red; + ori_scan += 3; + continue; + } + *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); + *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); + *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Red, src_alpha); } - void CFX_SkiaRenderer::CompositeSpanRGB24_10(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan) - { - dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + span_left+(span_left<<1); - dest_extra_alpha_scan = (uint8_t*)m_pDevice->m_pAlphaMask->GetScanline(span_top)+span_left; - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - if (col_end < col_start) return; // do nothing. - dest_scan += col_start+(col_start<<1); + } else { + for (int col = col_start; col < col_end; col++) { + int src_alpha = m_Alpha * clip_scan[col] / 255; + if (src_alpha == 255 && cover_scan == 255) { + *dest_scan++ = m_Blue; + *dest_scan++ = m_Green; + *dest_scan++ = m_Red; + ori_scan += 3; + continue; + } + int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); + int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); + int r = FXDIB_ALPHA_MERGE(*ori_scan++, m_Red, src_alpha); + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan); + dest_scan++; + } + } +#endif +} +void CFX_SkiaRenderer::CompositeSpanRGB24_10(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan) { + dest_scan = + (uint8_t*)m_pDevice->GetScanline(span_top) + span_left + (span_left << 1); + dest_extra_alpha_scan = + (uint8_t*)m_pDevice->m_pAlphaMask->GetScanline(span_top) + span_left; + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = + (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); + if (col_end < col_start) + return; // do nothing. + dest_scan += col_start + (col_start << 1); #if 1 - if (m_Alpha == 255 && cover_scan == 255) { - for (int col = col_start; col < col_end; col ++) { - *dest_scan++ = (uint8_t)m_Blue; - *dest_scan++ = (uint8_t)m_Green; - *dest_scan++ = (uint8_t)m_Red; - *dest_extra_alpha_scan++ = 255; - } - return; - } - int src_alpha = m_Alpha * cover_scan / 255; - for (int col = col_start; col < col_end; col ++) { - // Dest format: Rgba - // calculate destination alpha (it's union of source and dest alpha) - uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha - - (*dest_extra_alpha_scan) * src_alpha / 255; - *dest_extra_alpha_scan++ = dest_alpha; - int alpha_ratio = src_alpha*255/dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); - dest_scan ++; - } + if (m_Alpha == 255 && cover_scan == 255) { + for (int col = col_start; col < col_end; col++) { + *dest_scan++ = (uint8_t)m_Blue; + *dest_scan++ = (uint8_t)m_Green; + *dest_scan++ = (uint8_t)m_Red; + *dest_extra_alpha_scan++ = 255; + } + return; + } + int src_alpha = m_Alpha * cover_scan / 255; + for (int col = col_start; col < col_end; col++) { + // Dest format: Rgba + // calculate destination alpha (it's union of source and dest alpha) + uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha - + (*dest_extra_alpha_scan) * src_alpha / 255; + *dest_extra_alpha_scan++ = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); + dest_scan++; + } #else - if (m_bFullCover) { - if (m_Alpha == 255) { - for (int col = col_start; col < col_end; col ++) { - *dest_scan++ = (uint8_t)m_Blue; - *dest_scan++ = (uint8_t)m_Green; - *dest_scan++ = (uint8_t)m_Red; - *dest_extra_alpha_scan++ = 255; - } - return; - } - for (int col = col_start; col < col_end; col ++) { - // Dest format: Rgba - // calculate destination alpha (it's union of source and dest alpha) - uint8_t dest_alpha = (*dest_extra_alpha_scan) + m_Alpha - - (*dest_extra_alpha_scan) * m_Alpha / 255; - *dest_extra_alpha_scan++ = dest_alpha; - int alpha_ratio = m_Alpha*255/dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); - dest_scan ++; - } - } else { - if (m_Alpha == 255 && cover_scan == 255) { - for (int col = col_start; col < col_end; col ++) { - *dest_scan++ = (uint8_t)m_Blue; - *dest_scan++ = (uint8_t)m_Green; - *dest_scan++ = (uint8_t)m_Red; - *dest_extra_alpha_scan++ = 255; - } - return; - } - int src_alpha = m_Alpha * cover_scan / 255; - for (int col = col_start; col < col_end; col ++) { - // Dest format: Rgba - // calculate destination alpha (it's union of source and dest alpha) - uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha - - (*dest_extra_alpha_scan) * src_alpha / 255; - *dest_extra_alpha_scan++ = dest_alpha; - int alpha_ratio = src_alpha*255/dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); - dest_scan ++; - } - } -#endif + if (m_bFullCover) { + if (m_Alpha == 255) { + for (int col = col_start; col < col_end; col++) { + *dest_scan++ = (uint8_t)m_Blue; + *dest_scan++ = (uint8_t)m_Green; + *dest_scan++ = (uint8_t)m_Red; + *dest_extra_alpha_scan++ = 255; + } + return; + } + for (int col = col_start; col < col_end; col++) { + // Dest format: Rgba + // calculate destination alpha (it's union of source and dest alpha) + uint8_t dest_alpha = (*dest_extra_alpha_scan) + m_Alpha - + (*dest_extra_alpha_scan) * m_Alpha / 255; + *dest_extra_alpha_scan++ = dest_alpha; + int alpha_ratio = m_Alpha * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); + dest_scan++; } - void CFX_SkiaRenderer::CompositeSpanRGB24_14(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan) - { - dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + span_left+(span_left<<1); - dest_extra_alpha_scan = (uint8_t*)m_pDevice->m_pAlphaMask->GetScanline(span_top)+span_left; - clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top-clip_top) - clip_left + span_left; - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - if (col_end < col_start) return; // do nothing. - dest_scan += col_start + (col_start << 1); + } else { + if (m_Alpha == 255 && cover_scan == 255) { + for (int col = col_start; col < col_end; col++) { + *dest_scan++ = (uint8_t)m_Blue; + *dest_scan++ = (uint8_t)m_Green; + *dest_scan++ = (uint8_t)m_Red; + *dest_extra_alpha_scan++ = 255; + } + return; + } + int src_alpha = m_Alpha * cover_scan / 255; + for (int col = col_start; col < col_end; col++) { + // Dest format: Rgba + // calculate destination alpha (it's union of source and dest alpha) + uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha - + (*dest_extra_alpha_scan) * src_alpha / 255; + *dest_extra_alpha_scan++ = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); + dest_scan++; + } + } +#endif +} +void CFX_SkiaRenderer::CompositeSpanRGB24_14(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan) { + dest_scan = + (uint8_t*)m_pDevice->GetScanline(span_top) + span_left + (span_left << 1); + dest_extra_alpha_scan = + (uint8_t*)m_pDevice->m_pAlphaMask->GetScanline(span_top) + span_left; + clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top - clip_top) - + clip_left + span_left; + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = + (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); + if (col_end < col_start) + return; // do nothing. + dest_scan += col_start + (col_start << 1); #if 1 - int src_alpha = m_Alpha * cover_scan / 255; - for (int col = col_start; col < col_end; col ++) { - int src_alpha1 = src_alpha * clip_scan[col] / 255; - if (!src_alpha1) { - dest_extra_alpha_scan++; - dest_scan += 3; - continue; - } - if (src_alpha1 == 255) { - *dest_scan++ = (uint8_t)m_Blue; - *dest_scan++ = (uint8_t)m_Green; - *dest_scan++ = (uint8_t)m_Red; - *dest_extra_alpha_scan++ = (uint8_t)m_Alpha; - } else { - // Dest format: Rgba - // calculate destination alpha (it's union of source and dest alpha) - uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha1 - - (*dest_extra_alpha_scan) * src_alpha1 / 255; - *dest_extra_alpha_scan++ = dest_alpha; - int alpha_ratio = src_alpha1*255/dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); - dest_scan ++; - } - } + int src_alpha = m_Alpha * cover_scan / 255; + for (int col = col_start; col < col_end; col++) { + int src_alpha1 = src_alpha * clip_scan[col] / 255; + if (!src_alpha1) { + dest_extra_alpha_scan++; + dest_scan += 3; + continue; + } + if (src_alpha1 == 255) { + *dest_scan++ = (uint8_t)m_Blue; + *dest_scan++ = (uint8_t)m_Green; + *dest_scan++ = (uint8_t)m_Red; + *dest_extra_alpha_scan++ = (uint8_t)m_Alpha; + } else { + // Dest format: Rgba + // calculate destination alpha (it's union of source and dest alpha) + uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha1 - + (*dest_extra_alpha_scan) * src_alpha1 / 255; + *dest_extra_alpha_scan++ = dest_alpha; + int alpha_ratio = src_alpha1 * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); + dest_scan++; + } + } #else - if (m_bFullCover) { - for (int col = col_start; col < col_end; col ++) { - int src_alpha = m_Alpha * clip_scan[col] / 255; - if (!src_alpha) { - dest_extra_alpha_scan++; - dest_scan += 3; - continue; - } - if (src_alpha == 255) { - *dest_scan++ = (uint8_t)m_Blue; - *dest_scan++ = (uint8_t)m_Green; - *dest_scan++ = (uint8_t)m_Red; - *dest_extra_alpha_scan++ = (uint8_t)m_Alpha; - } else { - // Dest format: Rgba - // calculate destination alpha (it's union of source and dest alpha) - uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha - - (*dest_extra_alpha_scan) * src_alpha / 255; - *dest_extra_alpha_scan++ = dest_alpha; - int alpha_ratio = src_alpha*255/dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); - dest_scan ++; - } - } - } else { - int src_alpha = m_Alpha * cover_scan / 255; - for (int col = col_start; col < col_end; col ++) { - int src_alpha1 = m_Alpha * cover_scan * clip_scan[col] / 255; - if (!src_alpha1) { - dest_extra_alpha_scan++; - dest_scan += 3; - continue; - } - if (src_alpha1 == 255) { - *dest_scan++ = (uint8_t)m_Blue; - *dest_scan++ = (uint8_t)m_Green; - *dest_scan++ = (uint8_t)m_Red; - *dest_extra_alpha_scan++ = (uint8_t)m_Alpha; - } else { - // Dest format: Rgba - // calculate destination alpha (it's union of source and dest alpha) - uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha1 - - (*dest_extra_alpha_scan) * src_alpha1 / 255; - *dest_extra_alpha_scan++ = dest_alpha; - int alpha_ratio = src_alpha1*255/dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); - dest_scan ++; - } - } - } -#endif + if (m_bFullCover) { + for (int col = col_start; col < col_end; col++) { + int src_alpha = m_Alpha * clip_scan[col] / 255; + if (!src_alpha) { + dest_extra_alpha_scan++; + dest_scan += 3; + continue; + } + if (src_alpha == 255) { + *dest_scan++ = (uint8_t)m_Blue; + *dest_scan++ = (uint8_t)m_Green; + *dest_scan++ = (uint8_t)m_Red; + *dest_extra_alpha_scan++ = (uint8_t)m_Alpha; + } else { + // Dest format: Rgba + // calculate destination alpha (it's union of source and dest alpha) + uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha - + (*dest_extra_alpha_scan) * src_alpha / 255; + *dest_extra_alpha_scan++ = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); + dest_scan++; + } + } + } else { + int src_alpha = m_Alpha * cover_scan / 255; + for (int col = col_start; col < col_end; col++) { + int src_alpha1 = m_Alpha * cover_scan * clip_scan[col] / 255; + if (!src_alpha1) { + dest_extra_alpha_scan++; + dest_scan += 3; + continue; + } + if (src_alpha1 == 255) { + *dest_scan++ = (uint8_t)m_Blue; + *dest_scan++ = (uint8_t)m_Green; + *dest_scan++ = (uint8_t)m_Red; + *dest_extra_alpha_scan++ = (uint8_t)m_Alpha; + } else { + // Dest format: Rgba + // calculate destination alpha (it's union of source and dest alpha) + uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha1 - + (*dest_extra_alpha_scan) * src_alpha1 / 255; + *dest_extra_alpha_scan++ = dest_alpha; + int alpha_ratio = src_alpha1 * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); + dest_scan++; + } } - /*-----------------------------------------------------------------------------------------------------*/ + } +#endif +} +/*-----------------------------------------------------------------------------------------------------*/ - // A general alpha merge function (with clipping mask). Cmyka/Cmyk device. - void CFX_SkiaRenderer::CompositeSpanCMYK(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan) - { - ASSERT(!m_bRgbByteOrder); - // Cmyk(a) - int col_start = span_left < clip_left ? clip_left - span_left : 0; - int col_end = (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); - if (col_end < col_start) return; // do nothing. - dest_scan += col_start * 4; - Bpp; // for avoid compile warning. +// A general alpha merge function (with clipping mask). Cmyka/Cmyk device. +void CFX_SkiaRenderer::CompositeSpanCMYK(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan) { + ASSERT(!m_bRgbByteOrder); + // Cmyk(a) + int col_start = span_left < clip_left ? clip_left - span_left : 0; + int col_end = + (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); + if (col_end < col_start) + return; // do nothing. + dest_scan += col_start * 4; + Bpp; // for avoid compile warning. - if (dest_extra_alpha_scan) { - // CMYKa - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (m_bFullCover) { - if (clip_scan) - src_alpha = m_Alpha * clip_scan[col] / 255; - else - src_alpha = m_Alpha; - } else { - if (clip_scan) - src_alpha = m_Alpha * cover_scan * clip_scan[col] / 255 / 255; - else - src_alpha = m_Alpha * cover_scan / 255; - } + if (dest_extra_alpha_scan) { + // CMYKa + for (int col = col_start; col < col_end; col++) { + int src_alpha; + if (m_bFullCover) { + if (clip_scan) + src_alpha = m_Alpha * clip_scan[col] / 255; + else + src_alpha = m_Alpha; + } else { + if (clip_scan) + src_alpha = m_Alpha * cover_scan * clip_scan[col] / 255 / 255; + else + src_alpha = m_Alpha * cover_scan / 255; + } - if (src_alpha) { - if (src_alpha == 255) { - *(FX_CMYK*)dest_scan = m_Color; - *dest_extra_alpha_scan = (uint8_t)m_Alpha; - } else { - // Dest format: Cmyka - // calculate destination alpha (it's union of source and dest alpha) - uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha - - (*dest_extra_alpha_scan) * src_alpha / 255; - *dest_extra_alpha_scan++ = dest_alpha; - int alpha_ratio = src_alpha*255/dest_alpha; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, alpha_ratio); - dest_scan ++; - continue; - } - } - dest_extra_alpha_scan++; - dest_scan += 4; - } + if (src_alpha) { + if (src_alpha == 255) { + *(FX_CMYK*)dest_scan = m_Color; + *dest_extra_alpha_scan = (uint8_t)m_Alpha; } else { - // CMYK - for (int col = col_start; col < col_end; col ++) { - int src_alpha; - if (clip_scan) - src_alpha = m_Alpha * cover_scan * clip_scan[col] / 255 / 255; - else - src_alpha = m_Alpha * cover_scan / 255; - - if (src_alpha) { - if (src_alpha == 255) { - *(FX_CMYK*)dest_scan = m_Color; - } else { - // Dest format: cmyk - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha); - dest_scan ++; - *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, src_alpha); - dest_scan ++; - continue; - } - } - dest_scan += 4; - } + // Dest format: Cmyka + // calculate destination alpha (it's union of source and dest alpha) + uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha - + (*dest_extra_alpha_scan) * src_alpha / 255; + *dest_extra_alpha_scan++ = dest_alpha; + int alpha_ratio = src_alpha * 255 / dest_alpha; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, alpha_ratio); + dest_scan++; + continue; } + } + dest_extra_alpha_scan++; + dest_scan += 4; } + } else { + // CMYK + for (int col = col_start; col < col_end; col++) { + int src_alpha; + if (clip_scan) + src_alpha = m_Alpha * cover_scan * clip_scan[col] / 255 / 255; + else + src_alpha = m_Alpha * cover_scan / 255; - - - //-------------------------------------------------------------------- - FX_BOOL CFX_SkiaRenderer::Init(CFX_DIBitmap* pDevice, CFX_DIBitmap* pOriDevice, const CFX_ClipRgn* pClipRgn, FX_DWORD color, FX_BOOL bFullCover, FX_BOOL bRgbByteOrder, - int alpha_flag, void* pIccTransform) //The alpha flag must be fill_flag if exist. - { - m_pDevice = pDevice; - m_pClipRgn = pClipRgn; - m_bRgbByteOrder = bRgbByteOrder; - m_pOriDevice = pOriDevice; - m_pDestScan = NULL; - m_pDestExtraAlphaScan = NULL; - m_pOriScan = NULL; - m_pClipScan = NULL; - composite_span = NULL; - if (m_pClipRgn) - m_ClipBox = m_pClipRgn->GetBox(); - else { - m_ClipBox.left = m_ClipBox.top = 0; - m_ClipBox.right = m_pDevice->GetWidth(); - m_ClipBox.bottom = m_pDevice->GetHeight(); - } - m_pClipMask = NULL; - if (m_pClipRgn && m_pClipRgn->GetType() == CFX_ClipRgn::MaskF) - { - m_pClipMask = m_pClipRgn->GetMask(); - m_pClipScan = m_pClipMask->GetBuffer(); + if (src_alpha) { + if (src_alpha == 255) { + *(FX_CMYK*)dest_scan = m_Color; + } else { + // Dest format: cmyk + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha); + dest_scan++; + *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, src_alpha); + dest_scan++; + continue; } - if (m_pDevice->m_pAlphaMask) - m_pDestExtraAlphaScan = m_pDevice->m_pAlphaMask->GetBuffer(); - if (m_pOriDevice) - m_pOriScan = m_pOriDevice->GetBuffer(); - m_pDestScan = m_pDevice->GetBuffer(); - - m_bFullCover = bFullCover; + } + dest_scan += 4; + } + } +} - FX_BOOL bObjectCMYK = FXGETFLAG_COLORTYPE(alpha_flag); - FX_BOOL bDeviceCMYK = pDevice->IsCmykImage(); +//-------------------------------------------------------------------- +FX_BOOL CFX_SkiaRenderer::Init( + CFX_DIBitmap* pDevice, + CFX_DIBitmap* pOriDevice, + const CFX_ClipRgn* pClipRgn, + FX_DWORD color, + FX_BOOL bFullCover, + FX_BOOL bRgbByteOrder, + int alpha_flag, + void* pIccTransform) // The alpha flag must be fill_flag if exist. +{ + m_pDevice = pDevice; + m_pClipRgn = pClipRgn; + m_bRgbByteOrder = bRgbByteOrder; + m_pOriDevice = pOriDevice; + m_pDestScan = NULL; + m_pDestExtraAlphaScan = NULL; + m_pOriScan = NULL; + m_pClipScan = NULL; + composite_span = NULL; + if (m_pClipRgn) + m_ClipBox = m_pClipRgn->GetBox(); + else { + m_ClipBox.left = m_ClipBox.top = 0; + m_ClipBox.right = m_pDevice->GetWidth(); + m_ClipBox.bottom = m_pDevice->GetHeight(); + } + m_pClipMask = NULL; + if (m_pClipRgn && m_pClipRgn->GetType() == CFX_ClipRgn::MaskF) { + m_pClipMask = m_pClipRgn->GetMask(); + m_pClipScan = m_pClipMask->GetBuffer(); + } + if (m_pDevice->m_pAlphaMask) + m_pDestExtraAlphaScan = m_pDevice->m_pAlphaMask->GetBuffer(); + if (m_pOriDevice) + m_pOriScan = m_pOriDevice->GetBuffer(); + m_pDestScan = m_pDevice->GetBuffer(); - m_Alpha = bObjectCMYK ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(color); + m_bFullCover = bFullCover; - ICodec_IccModule* pIccModule = NULL; - // No lcms engine, we skip the transform - if (!CFX_GEModule::Get()->GetCodecModule() || !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) - pIccTransform = NULL; - else - pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); + FX_BOOL bObjectCMYK = FXGETFLAG_COLORTYPE(alpha_flag); + FX_BOOL bDeviceCMYK = pDevice->IsCmykImage(); - if (m_pDevice->GetBPP() == 8) { // Gray(a) device - ASSERT(!m_bRgbByteOrder); - if (m_pDevice->IsAlphaMask()) { - //Alpha Mask - m_Gray = 255; - } else { - //Gray(a) device - if (pIccTransform) { - uint8_t gray; - color = bObjectCMYK ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); - pIccModule->TranslateScanline(pIccTransform, &gray, (const uint8_t*)&color, 1); - m_Gray = gray; - } else { - if (bObjectCMYK) { - uint8_t r, g, b; - AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), FXSYS_GetYValue(color), FXSYS_GetKValue(color), - r, g, b); - m_Gray = FXRGB2GRAY(r, g, b); - } else { - m_Gray = FXRGB2GRAY(FXARGB_R(color), FXARGB_G(color), FXARGB_B(color)); - } - } - } - } else { - if (bDeviceCMYK) { // Cmyk(a) Device - ASSERT(!m_bRgbByteOrder); - //TODO... opt for cmyk - composite_span = &CFX_SkiaRenderer::CompositeSpanCMYK; - if (bObjectCMYK) { - m_Color = FXCMYK_TODIB(color); - if (pIccTransform) - pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&m_Color, (const uint8_t*)&m_Color, 1); - } else { // Object RGB - if (!pIccTransform) - return FALSE; - color = FXARGB_TODIB(color); - pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&m_Color, (const uint8_t*)&color, 1); - } - m_Red = ((uint8_t*)&m_Color)[0]; - m_Green = ((uint8_t*)&m_Color)[1]; - m_Blue = ((uint8_t*)&m_Color)[2]; - m_Gray = ((uint8_t*)&m_Color)[3]; - return TRUE; - } - if (pIccTransform) { - color = bObjectCMYK ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); - pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&m_Color, (const uint8_t*)&color, 1); - ((uint8_t*)&m_Color)[3] = m_Alpha; - m_Red = ((uint8_t*)&m_Color)[2]; - m_Green = ((uint8_t*)&m_Color)[1]; - m_Blue = ((uint8_t*)&m_Color)[0]; - // Need Johnson to improvement it. - if (m_bRgbByteOrder) { - // swap - m_Red = ((uint8_t*)&m_Color)[0]; - m_Blue = ((uint8_t*)&m_Color)[2]; - m_Color = FXARGB_TODIB(m_Color); - m_Color = FXARGB_TOBGRORDERDIB(m_Color); - } - } else { - if (bObjectCMYK) { - uint8_t r, g, b; - AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), FXSYS_GetYValue(color), FXSYS_GetKValue(color), - r, g, b); - m_Color = FXARGB_MAKE(m_Alpha, r, g, b); - if (m_bRgbByteOrder){ - m_Color = FXARGB_TOBGRORDERDIB(m_Color); - m_Red = b; m_Green = g; m_Blue = r;// - }else { - m_Color = FXARGB_TODIB(m_Color); - m_Red = r; m_Green = g; m_Blue = b;// - } - } else { - if (m_bRgbByteOrder){ - m_Color = FXARGB_TOBGRORDERDIB(color); - ArgbDecode(color, m_Alpha, m_Blue, m_Green, m_Red); // - }else { - m_Color = FXARGB_TODIB(color); - ArgbDecode(color, m_Alpha, m_Red, m_Green, m_Blue); - } - } - } - } - // Get palette transparency selector - m_ProcessFilter = (m_pOriDevice? 1 : 0) /* has Ori Device flag */ - + (m_pDevice->GetBPP() >= 8 ? 2 : 0) /* bpp flag */ - + (m_pClipMask? 4 : 0) /* has clip region flag */ - + (m_pDevice->m_pAlphaMask? 8 : 0); /* has Alpha Mask chanel flag */ - switch(m_ProcessFilter) { - case 0: - composite_span = &CFX_SkiaRenderer::CompositeSpan1bpp_0; - break; - case 2: - { - if (m_pDevice->GetBPP() == 8) - composite_span = &CFX_SkiaRenderer::CompositeSpanGray_2; - else if (m_pDevice->GetBPP() == 24) - composite_span = &CFX_SkiaRenderer::CompositeSpanRGB24_2; - else - composite_span = m_pDevice->HasAlpha()?&CFX_SkiaRenderer::CompositeSpanARGB_2 : &CFX_SkiaRenderer::CompositeSpanRGB32_2; - } - break; - case 3: - { - if (m_pDevice->GetBPP() == 8) - composite_span = &CFX_SkiaRenderer::CompositeSpanGray_3; - else if (m_pDevice->GetBPP() == 24) - composite_span = &CFX_SkiaRenderer::CompositeSpanRGB24_3; - else - composite_span = m_pDevice->HasAlpha()?&CFX_SkiaRenderer::CompositeSpanARGB_3 : &CFX_SkiaRenderer::CompositeSpanRGB32_3; - } - break; - case 4: - composite_span = &CFX_SkiaRenderer::CompositeSpan1bpp_4; - break; - case 6: - { - if (m_pDevice->GetBPP() == 8) - composite_span = &CFX_SkiaRenderer::CompositeSpanGray_6; - else if (m_pDevice->GetBPP() == 24) - composite_span = &CFX_SkiaRenderer::CompositeSpanRGB24_6; - else - composite_span = m_pDevice->HasAlpha()?&CFX_SkiaRenderer::CompositeSpanARGB_6 : &CFX_SkiaRenderer::CompositeSpanRGB32_6; - } - break; - case 7: - { - if (m_pDevice->GetBPP() == 8) - composite_span = &CFX_SkiaRenderer::CompositeSpanGray_7; - else if (m_pDevice->GetBPP() == 24) - composite_span = &CFX_SkiaRenderer::CompositeSpanRGB24_7; - else - composite_span = m_pDevice->HasAlpha()?&CFX_SkiaRenderer::CompositeSpanARGB_7 : &CFX_SkiaRenderer::CompositeSpanRGB32_7; - } - break; - case 1: - case 5: - case 8: - case 9: - case 11: - case 12: - case 13: - case 15: - //TODO... - break; - case 10: - composite_span = &CFX_SkiaRenderer::CompositeSpanRGB24_10; - break; - case 14: - composite_span = &CFX_SkiaRenderer::CompositeSpanRGB24_14; - break; - } - if (composite_span == NULL) - return FALSE; - return TRUE; - } + m_Alpha = bObjectCMYK ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(color); - /*----------------------------------------------------------------------------------------------------*/ - void CFX_SkiaA8Renderer::blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]) - { - FXSYS_assert(m_pDevice); - int dst_y = y - m_Top; - if (dst_y < 0 || dst_y >= m_pDevice->GetHeight()) - return; + ICodec_IccModule* pIccModule = NULL; + // No lcms engine, we skip the transform + if (!CFX_GEModule::Get()->GetCodecModule() || + !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) + pIccTransform = NULL; + else + pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); - uint8_t* dest_scan = m_pDevice->GetBuffer() + m_pDevice->GetPitch() * dst_y; - uint8_t* dest_pos = dest_scan; - while (1) - { - if (x >= m_dstWidth) - return; - int width = runs[0]; - SkASSERT(width >= 0); - if (width <= 0) - return; - unsigned aa = antialias[0]; - if (aa) { - int col_start = x < m_Left ? 0 : x - m_Left; - int col_end = x + width; - col_end = col_end < m_dstWidth ? col_end - m_Left: m_pDevice->GetWidth(); - int result = col_end - col_start; - if (result > 0) { - dest_pos = dest_scan + col_start; - if (result >= 4) - FXSYS_memset(dest_pos, FXARGB_MAKE(aa, aa, aa, aa),result); - else - FXSYS_memset(dest_pos,aa,result); - } - } - runs += width; - antialias += width; - x += width; + if (m_pDevice->GetBPP() == 8) { // Gray(a) device + ASSERT(!m_bRgbByteOrder); + if (m_pDevice->IsAlphaMask()) { + // Alpha Mask + m_Gray = 255; + } else { + // Gray(a) device + if (pIccTransform) { + uint8_t gray; + color = bObjectCMYK ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); + pIccModule->TranslateScanline(pIccTransform, &gray, + (const uint8_t*)&color, 1); + m_Gray = gray; + } else { + if (bObjectCMYK) { + uint8_t r, g, b; + AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), + FXSYS_GetYValue(color), FXSYS_GetKValue(color), r, + g, b); + m_Gray = FXRGB2GRAY(r, g, b); + } else { + m_Gray = + FXRGB2GRAY(FXARGB_R(color), FXARGB_G(color), FXARGB_B(color)); } + } } - void CFX_SkiaA8Renderer::blitH(int x, int y, int width) - { - FXSYS_assert(m_pDevice); - int dst_y = y - m_Top; - if (dst_y < 0 || dst_y >= m_pDevice->GetHeight()) - return; - if (x >= m_dstWidth) - return; - uint8_t* dest_scan = m_pDevice->GetBuffer() + m_pDevice->GetPitch() * dst_y; - int col_start = x < m_Left ? 0 : x - m_Left; - int col_end = x + width; - col_end = col_end < m_dstWidth ? col_end - m_Left: m_pDevice->GetWidth(); - int result = col_end - col_start; - if (result > 0) { - uint8_t* dest_pos = dest_scan + col_start; - if (result >= 4) - FXSYS_memset(dest_pos, 0xffffffff,result); - else - FXSYS_memset(dest_pos,255,result); - } + } else { + if (bDeviceCMYK) { // Cmyk(a) Device + ASSERT(!m_bRgbByteOrder); + // TODO... opt for cmyk + composite_span = &CFX_SkiaRenderer::CompositeSpanCMYK; + if (bObjectCMYK) { + m_Color = FXCMYK_TODIB(color); + if (pIccTransform) + pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&m_Color, + (const uint8_t*)&m_Color, 1); + } else { // Object RGB + if (!pIccTransform) + return FALSE; + color = FXARGB_TODIB(color); + pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&m_Color, + (const uint8_t*)&color, 1); + } + m_Red = ((uint8_t*)&m_Color)[0]; + m_Green = ((uint8_t*)&m_Color)[1]; + m_Blue = ((uint8_t*)&m_Color)[2]; + m_Gray = ((uint8_t*)&m_Color)[3]; + return TRUE; } - void CFX_SkiaA8Renderer::blitV(int x, int y, int height, SkAlpha alpha) - { - FXSYS_assert(alpha); - if (alpha == 255) { - blitRect(x, y, 1, height); + if (pIccTransform) { + color = bObjectCMYK ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); + pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&m_Color, + (const uint8_t*)&color, 1); + ((uint8_t*)&m_Color)[3] = m_Alpha; + m_Red = ((uint8_t*)&m_Color)[2]; + m_Green = ((uint8_t*)&m_Color)[1]; + m_Blue = ((uint8_t*)&m_Color)[0]; + // Need Johnson to improvement it. + if (m_bRgbByteOrder) { + // swap + m_Red = ((uint8_t*)&m_Color)[0]; + m_Blue = ((uint8_t*)&m_Color)[2]; + m_Color = FXARGB_TODIB(m_Color); + m_Color = FXARGB_TOBGRORDERDIB(m_Color); + } + } else { + if (bObjectCMYK) { + uint8_t r, g, b; + AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), + FXSYS_GetYValue(color), FXSYS_GetKValue(color), r, g, + b); + m_Color = FXARGB_MAKE(m_Alpha, r, g, b); + if (m_bRgbByteOrder) { + m_Color = FXARGB_TOBGRORDERDIB(m_Color); + m_Red = b; + m_Green = g; + m_Blue = r; // } else { - int16_t runs[2]; - runs[0] = 1; - runs[1] = 0; - while (--height >= 0) { - if (y >= m_dstHeight) - return; - blitAntiH(x, y ++, &alpha, runs); - } + m_Color = FXARGB_TODIB(m_Color); + m_Red = r; + m_Green = g; + m_Blue = b; // } - } - void CFX_SkiaA8Renderer::blitRect(int x, int y, int width, int height) - { - FXSYS_assert(m_pDevice); - while (--height >= 0) { - if (y >= m_dstHeight) - return; - blitH(x , y ++, width); + } else { + if (m_bRgbByteOrder) { + m_Color = FXARGB_TOBGRORDERDIB(color); + ArgbDecode(color, m_Alpha, m_Blue, m_Green, m_Red); // + } else { + m_Color = FXARGB_TODIB(color); + ArgbDecode(color, m_Alpha, m_Red, m_Green, m_Blue); } + } } + } + // Get palette transparency selector + m_ProcessFilter = + (m_pOriDevice ? 1 : 0) /* has Ori Device flag */ + + (m_pDevice->GetBPP() >= 8 ? 2 : 0) /* bpp flag */ + + (m_pClipMask ? 4 : 0) /* has clip region flag */ + + (m_pDevice->m_pAlphaMask ? 8 : 0); /* has Alpha Mask chanel flag */ + switch (m_ProcessFilter) { + case 0: + composite_span = &CFX_SkiaRenderer::CompositeSpan1bpp_0; + break; + case 2: { + if (m_pDevice->GetBPP() == 8) + composite_span = &CFX_SkiaRenderer::CompositeSpanGray_2; + else if (m_pDevice->GetBPP() == 24) + composite_span = &CFX_SkiaRenderer::CompositeSpanRGB24_2; + else + composite_span = m_pDevice->HasAlpha() + ? &CFX_SkiaRenderer::CompositeSpanARGB_2 + : &CFX_SkiaRenderer::CompositeSpanRGB32_2; + } break; + case 3: { + if (m_pDevice->GetBPP() == 8) + composite_span = &CFX_SkiaRenderer::CompositeSpanGray_3; + else if (m_pDevice->GetBPP() == 24) + composite_span = &CFX_SkiaRenderer::CompositeSpanRGB24_3; + else + composite_span = m_pDevice->HasAlpha() + ? &CFX_SkiaRenderer::CompositeSpanARGB_3 + : &CFX_SkiaRenderer::CompositeSpanRGB32_3; + } break; + case 4: + composite_span = &CFX_SkiaRenderer::CompositeSpan1bpp_4; + break; + case 6: { + if (m_pDevice->GetBPP() == 8) + composite_span = &CFX_SkiaRenderer::CompositeSpanGray_6; + else if (m_pDevice->GetBPP() == 24) + composite_span = &CFX_SkiaRenderer::CompositeSpanRGB24_6; + else + composite_span = m_pDevice->HasAlpha() + ? &CFX_SkiaRenderer::CompositeSpanARGB_6 + : &CFX_SkiaRenderer::CompositeSpanRGB32_6; + } break; + case 7: { + if (m_pDevice->GetBPP() == 8) + composite_span = &CFX_SkiaRenderer::CompositeSpanGray_7; + else if (m_pDevice->GetBPP() == 24) + composite_span = &CFX_SkiaRenderer::CompositeSpanRGB24_7; + else + composite_span = m_pDevice->HasAlpha() + ? &CFX_SkiaRenderer::CompositeSpanARGB_7 + : &CFX_SkiaRenderer::CompositeSpanRGB32_7; + } break; + case 1: + case 5: + case 8: + case 9: + case 11: + case 12: + case 13: + case 15: + // TODO... + break; + case 10: + composite_span = &CFX_SkiaRenderer::CompositeSpanRGB24_10; + break; + case 14: + composite_span = &CFX_SkiaRenderer::CompositeSpanRGB24_14; + break; + } + if (composite_span == NULL) + return FALSE; + return TRUE; +} - void CFX_SkiaA8Renderer::blitAntiRect(int x, int y, int width, int height, - SkAlpha leftAlpha, SkAlpha rightAlpha) - { - blitV(x++, y, height, leftAlpha); - if (width > 0) { - blitRect(x, y, width, height); - x += width; - } - blitV(x, y, height, rightAlpha); - } +/*----------------------------------------------------------------------------------------------------*/ +void CFX_SkiaA8Renderer::blitAntiH(int x, + int y, + const SkAlpha antialias[], + const int16_t runs[]) { + FXSYS_assert(m_pDevice); + int dst_y = y - m_Top; + if (dst_y < 0 || dst_y >= m_pDevice->GetHeight()) + return; - FX_BOOL CFX_SkiaA8Renderer::Init(CFX_DIBitmap* pDevice, int Left, int Top) - { - m_pDevice = pDevice; - m_Left = Left; - m_Top = Top; - if (pDevice){ - m_dstWidth = m_Left + pDevice->GetWidth(); - m_dstHeight = m_Top + pDevice->GetHeight(); - } - return TRUE; + uint8_t* dest_scan = m_pDevice->GetBuffer() + m_pDevice->GetPitch() * dst_y; + uint8_t* dest_pos = dest_scan; + while (1) { + if (x >= m_dstWidth) + return; + int width = runs[0]; + SkASSERT(width >= 0); + if (width <= 0) + return; + unsigned aa = antialias[0]; + if (aa) { + int col_start = x < m_Left ? 0 : x - m_Left; + int col_end = x + width; + col_end = col_end < m_dstWidth ? col_end - m_Left : m_pDevice->GetWidth(); + int result = col_end - col_start; + if (result > 0) { + dest_pos = dest_scan + col_start; + if (result >= 4) + FXSYS_memset(dest_pos, FXARGB_MAKE(aa, aa, aa, aa), result); + else + FXSYS_memset(dest_pos, aa, result); + } } + runs += width; + antialias += width; + x += width; + } +} +void CFX_SkiaA8Renderer::blitH(int x, int y, int width) { + FXSYS_assert(m_pDevice); + int dst_y = y - m_Top; + if (dst_y < 0 || dst_y >= m_pDevice->GetHeight()) + return; + if (x >= m_dstWidth) + return; + uint8_t* dest_scan = m_pDevice->GetBuffer() + m_pDevice->GetPitch() * dst_y; + int col_start = x < m_Left ? 0 : x - m_Left; + int col_end = x + width; + col_end = col_end < m_dstWidth ? col_end - m_Left : m_pDevice->GetWidth(); + int result = col_end - col_start; + if (result > 0) { + uint8_t* dest_pos = dest_scan + col_start; + if (result >= 4) + FXSYS_memset(dest_pos, 0xffffffff, result); + else + FXSYS_memset(dest_pos, 255, result); + } +} +void CFX_SkiaA8Renderer::blitV(int x, int y, int height, SkAlpha alpha) { + FXSYS_assert(alpha); + if (alpha == 255) { + blitRect(x, y, 1, height); + } else { + int16_t runs[2]; + runs[0] = 1; + runs[1] = 0; + while (--height >= 0) { + if (y >= m_dstHeight) + return; + blitAntiH(x, y++, &alpha, runs); + } + } +} +void CFX_SkiaA8Renderer::blitRect(int x, int y, int width, int height) { + FXSYS_assert(m_pDevice); + while (--height >= 0) { + if (y >= m_dstHeight) + return; + blitH(x, y++, width); + } +} + +void CFX_SkiaA8Renderer::blitAntiRect(int x, + int y, + int width, + int height, + SkAlpha leftAlpha, + SkAlpha rightAlpha) { + blitV(x++, y, height, leftAlpha); + if (width > 0) { + blitRect(x, y, width, height); + x += width; + } + blitV(x, y, height, rightAlpha); +} + +FX_BOOL CFX_SkiaA8Renderer::Init(CFX_DIBitmap* pDevice, int Left, int Top) { + m_pDevice = pDevice; + m_Left = Left; + m_Top = Top; + if (pDevice) { + m_dstWidth = m_Left + pDevice->GetWidth(); + m_dstHeight = m_Top + pDevice->GetHeight(); + } + return TRUE; +} #endif diff --git a/core/src/fxge/skia/fx_skia_blitter_new.h b/core/src/fxge/skia/fx_skia_blitter_new.h index e60c6398d2..36a6b438f1 100644 --- a/core/src/fxge/skia/fx_skia_blitter_new.h +++ b/core/src/fxge/skia/fx_skia_blitter_new.h @@ -6,224 +6,516 @@ #define CORE_SRC_FXGE_SKIA_FX_SKIA_BLITTER_NEW_H_ #if defined(_SKIA_SUPPORT_) -class CFX_SkiaRenderer : public SkBlitter -{ -protected: - int m_Alpha, - m_Red, // Or the complementary-color, Cyan - m_Green, // Magenta - m_Blue, // Yellow - m_Gray; // Black - FX_DWORD m_Color; // FX_ARGB or FX_CMYK - FX_BOOL m_bFullCover; - int m_ProcessFilter; - FX_BOOL m_bRgbByteOrder; - - FX_RECT m_ClipBox; - CFX_DIBitmap* m_pDevice; - CFX_DIBitmap* m_pOriDevice; - const CFX_ClipRgn* m_pClipRgn; - const CFX_DIBitmap* m_pClipMask; - - uint8_t* m_pDestScan; - uint8_t* m_pDestExtraAlphaScan; - uint8_t* m_pOriScan; - uint8_t* m_pClipScan; - - void (CFX_SkiaRenderer::*composite_span)(uint8_t*,uint8_t*,int,int,int,int,uint8_t,int,int,int,uint8_t*,uint8_t*); -public: - - //-------------------------------------------------------------------- - virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]); - virtual void blitH(int x, int y, int width); - virtual void blitV(int x, int y, int height, SkAlpha alpha); - virtual void blitRect(int x, int y, int width, int height); - virtual void blitAntiRect(int x, int y, int width, int height, SkAlpha leftAlpha, SkAlpha rightAlpha); - - /*------------------------------------------------------------------------------------------------------*/ - // A general alpha merge function (with clipping mask). Gray device. - void CompositeSpan1bpp_0(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - void CompositeSpan1bpp_1(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - void CompositeSpan1bpp_4(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - void CompositeSpan1bpp_5(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - void CompositeSpan1bpp_8(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - void CompositeSpan1bpp_9(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - void CompositeSpan1bpp_12(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - void CompositeSpan1bpp_13(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - - /*--------------------------------------------------------------------------------------------------------*/ - - // A general alpha merge function (with clipping mask). Gray device. - void CompositeSpanGray_2(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - - void CompositeSpanGray_3(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - - void CompositeSpanGray_6(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - - void CompositeSpanGray_7(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - - void CompositeSpanGray_10(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - - - void CompositeSpanGray_11(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - - void CompositeSpanGray_14(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - - void CompositeSpanGray_15(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - - /*--------------------------------------------------------------------------------------------------------*/ - void CompositeSpanARGB_2(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - - void CompositeSpanARGB_3(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - - - void CompositeSpanARGB_6(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - - - void CompositeSpanARGB_7(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - // ... - /*--------------------------------------------------------------------------------------------------------*/ - void CompositeSpanRGB32_2(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - void CompositeSpanRGB32_3(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - void CompositeSpanRGB32_6(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - void CompositeSpanRGB32_7(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - - /*---------------------------------------------------------------------------------------------------------*/ - - void CompositeSpanRGB24_2(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - void CompositeSpanRGB24_3(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - void CompositeSpanRGB24_6(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - void CompositeSpanRGB24_7(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - void CompositeSpanRGB24_10(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - void CompositeSpanRGB24_11(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - void CompositeSpanRGB24_14(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - void CompositeSpanRGB24_15(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - - /*----------------------------------------------------------------------------------------------------------*/ - - // A general alpha merge function (with clipping mask). Cmyka/Cmyk device. - void CompositeSpanCMYK(uint8_t* dest_scan, uint8_t* ori_scan,int Bpp, - int span_left, int span_len, int span_top, uint8_t cover_scan, - int clip_top, int clip_left, int clip_right, uint8_t* clip_scan, - uint8_t* dest_extra_alpha_scan); - - - //-------------------------------------------------------------------- - FX_BOOL Init(CFX_DIBitmap* pDevice, CFX_DIBitmap* pOriDevice, const CFX_ClipRgn* pClipRgn, FX_DWORD color, FX_BOOL bFullCover, FX_BOOL bRgbByteOrder, - int alpha_flag = 0, void* pIccTransform = NULL); //The alpha flag must be fill_flag if exist. +class CFX_SkiaRenderer : public SkBlitter { + protected: + int m_Alpha, + m_Red, // Or the complementary-color, Cyan + m_Green, // Magenta + m_Blue, // Yellow + m_Gray; // Black + FX_DWORD m_Color; // FX_ARGB or FX_CMYK + FX_BOOL m_bFullCover; + int m_ProcessFilter; + FX_BOOL m_bRgbByteOrder; + + FX_RECT m_ClipBox; + CFX_DIBitmap* m_pDevice; + CFX_DIBitmap* m_pOriDevice; + const CFX_ClipRgn* m_pClipRgn; + const CFX_DIBitmap* m_pClipMask; + + uint8_t* m_pDestScan; + uint8_t* m_pDestExtraAlphaScan; + uint8_t* m_pOriScan; + uint8_t* m_pClipScan; + + void (CFX_SkiaRenderer::*composite_span)(uint8_t*, + uint8_t*, + int, + int, + int, + int, + uint8_t, + int, + int, + int, + uint8_t*, + uint8_t*); + + public: + //-------------------------------------------------------------------- + virtual void blitAntiH(int x, + int y, + const SkAlpha antialias[], + const int16_t runs[]); + virtual void blitH(int x, int y, int width); + virtual void blitV(int x, int y, int height, SkAlpha alpha); + virtual void blitRect(int x, int y, int width, int height); + virtual void blitAntiRect(int x, + int y, + int width, + int height, + SkAlpha leftAlpha, + SkAlpha rightAlpha); + + /*------------------------------------------------------------------------------------------------------*/ + // A general alpha merge function (with clipping mask). Gray device. + void CompositeSpan1bpp_0(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + void CompositeSpan1bpp_1(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + void CompositeSpan1bpp_4(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + void CompositeSpan1bpp_5(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + void CompositeSpan1bpp_8(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + void CompositeSpan1bpp_9(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + void CompositeSpan1bpp_12(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + void CompositeSpan1bpp_13(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + + /*--------------------------------------------------------------------------------------------------------*/ + + // A general alpha merge function (with clipping mask). Gray device. + void CompositeSpanGray_2(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + + void CompositeSpanGray_3(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + + void CompositeSpanGray_6(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + + void CompositeSpanGray_7(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + + void CompositeSpanGray_10(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + + void CompositeSpanGray_11(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + + void CompositeSpanGray_14(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + + void CompositeSpanGray_15(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + + /*--------------------------------------------------------------------------------------------------------*/ + void CompositeSpanARGB_2(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + + void CompositeSpanARGB_3(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + + void CompositeSpanARGB_6(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + + void CompositeSpanARGB_7(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + // ... + /*--------------------------------------------------------------------------------------------------------*/ + void CompositeSpanRGB32_2(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + void CompositeSpanRGB32_3(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + void CompositeSpanRGB32_6(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + void CompositeSpanRGB32_7(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + + /*---------------------------------------------------------------------------------------------------------*/ + + void CompositeSpanRGB24_2(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + void CompositeSpanRGB24_3(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + void CompositeSpanRGB24_6(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + void CompositeSpanRGB24_7(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + void CompositeSpanRGB24_10(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + void CompositeSpanRGB24_11(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + void CompositeSpanRGB24_14(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + void CompositeSpanRGB24_15(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + + /*----------------------------------------------------------------------------------------------------------*/ + + // A general alpha merge function (with clipping mask). Cmyka/Cmyk device. + void CompositeSpanCMYK(uint8_t* dest_scan, + uint8_t* ori_scan, + int Bpp, + int span_left, + int span_len, + int span_top, + uint8_t cover_scan, + int clip_top, + int clip_left, + int clip_right, + uint8_t* clip_scan, + uint8_t* dest_extra_alpha_scan); + + //-------------------------------------------------------------------- + FX_BOOL Init(CFX_DIBitmap* pDevice, + CFX_DIBitmap* pOriDevice, + const CFX_ClipRgn* pClipRgn, + FX_DWORD color, + FX_BOOL bFullCover, + FX_BOOL bRgbByteOrder, + int alpha_flag = 0, + void* pIccTransform = + NULL); // The alpha flag must be fill_flag if exist. }; -class CFX_SkiaA8Renderer : public SkBlitter -{ -public: - //-------------------------------------------------------------------- - virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]); - virtual void blitH(int x, int y, int width); - virtual void blitV(int x, int y, int height, SkAlpha alpha); - virtual void blitRect(int x, int y, int width, int height); - virtual void blitAntiRect(int x, int y, int width, int height, SkAlpha leftAlpha, SkAlpha rightAlpha); - //-------------------------------------------------------------------- - FX_BOOL Init(CFX_DIBitmap* pDevice, int Left, int Top); - CFX_DIBitmap* m_pDevice; - int m_Left; - int m_Top; - int m_dstWidth; - int m_dstHeight; +class CFX_SkiaA8Renderer : public SkBlitter { + public: + //-------------------------------------------------------------------- + virtual void blitAntiH(int x, + int y, + const SkAlpha antialias[], + const int16_t runs[]); + virtual void blitH(int x, int y, int width); + virtual void blitV(int x, int y, int height, SkAlpha alpha); + virtual void blitRect(int x, int y, int width, int height); + virtual void blitAntiRect(int x, + int y, + int width, + int height, + SkAlpha leftAlpha, + SkAlpha rightAlpha); + //-------------------------------------------------------------------- + FX_BOOL Init(CFX_DIBitmap* pDevice, int Left, int Top); + CFX_DIBitmap* m_pDevice; + int m_Left; + int m_Top; + int m_dstWidth; + int m_dstHeight; }; #endif diff --git a/core/src/fxge/skia/fx_skia_device.cpp b/core/src/fxge/skia/fx_skia_device.cpp index 41ce077976..fcd8e9871e 100644 --- a/core/src/fxge/skia/fx_skia_device.cpp +++ b/core/src/fxge/skia/fx_skia_device.cpp @@ -7,27 +7,28 @@ #if defined(_SKIA_SUPPORT_) #include "../../../include/fxcodec/fx_codec.h" - //#define _FOXIT_DEBUG_ //#define _FOXIT_BENCHMARK_ extern "C" { - extern void FX_OUTPUT_LOG_FUNC(const char*, ...); - extern int FX_GET_TICK_FUNC(); +extern void FX_OUTPUT_LOG_FUNC(const char*, ...); +extern int FX_GET_TICK_FUNC(); }; #ifdef _FOXIT_DEBUG_ #define FOXIT_DEBUG1(msg) FX_OUTPUT_LOG_FUNC(msg) -#define FOXIT_DEBUG2(msg,para) FX_OUTPUT_LOG_FUNC(msg,para) -#define FOXIT_DEBUG3(msg,para1,para2) FX_OUTPUT_LOG_FUNC(msg,para1,para2) -#define FOXIT_DEBUG4(msg,para1,para2,para3) FX_OUTPUT_LOG_FUNC(msg,para1,para2,para3) -#define FOXIT_DEBUG5(msg,para1,para2,para3,param4) FX_OUTPUT_LOG_FUNC(msg,para1,para2,para3,param4) +#define FOXIT_DEBUG2(msg, para) FX_OUTPUT_LOG_FUNC(msg, para) +#define FOXIT_DEBUG3(msg, para1, para2) FX_OUTPUT_LOG_FUNC(msg, para1, para2) +#define FOXIT_DEBUG4(msg, para1, para2, para3) \ + FX_OUTPUT_LOG_FUNC(msg, para1, para2, para3) +#define FOXIT_DEBUG5(msg, para1, para2, para3, param4) \ + FX_OUTPUT_LOG_FUNC(msg, para1, para2, para3, param4) #else #define FOXIT_DEBUG1(msg) -#define FOXIT_DEBUG2(msg,para) -#define FOXIT_DEBUG3(msg,para1,para2) -#define FOXIT_DEBUG4(msg,para1,para2,para3) -#define FOXIT_DEBUG5(msg,para1,para2,para3,param4) +#define FOXIT_DEBUG2(msg, para) +#define FOXIT_DEBUG3(msg, para1, para2) +#define FOXIT_DEBUG4(msg, para1, para2, para3) +#define FOXIT_DEBUG5(msg, para1, para2, para3, param4) #endif #include "SkDashPathEffect.h" @@ -36,496 +37,593 @@ extern "C" { #include "SkRasterClip.h" #include "SkStroke.h" - #include "fx_skia_blitter_new.h" #include "../agg/fx_agg_driver.h" #include "fx_skia_device.h" /// Run-length-encoded supersampling antialiased blitter. -class SuperBlitter_skia -{ -public: - static void DrawPath(const SkPath& srcPath, SkBlitter* blitter, const SkRasterClip& rect, const SkPaint& origPaint); +class SuperBlitter_skia { + public: + static void DrawPath(const SkPath& srcPath, + SkBlitter* blitter, + const SkRasterClip& rect, + const SkPaint& origPaint); }; FX_BOOL FxSkDrawTreatAsHairline(const SkPaint& paint, SkScalar* coverage) { - if (SkPaint::kStroke_Style != paint.getStyle()) - return FALSE; - FXSYS_assert(coverage); - SkScalar strokeWidth = paint.getStrokeWidth(); - if (0 == strokeWidth) { - *coverage = SK_Scalar1; - return TRUE; - } - // if we get here, we need to try to fake a thick-stroke with a modulated - // hairline - if (!paint.isAntiAlias()) - return FALSE; - if (strokeWidth <= SK_Scalar1) { - *coverage = strokeWidth; - return TRUE; - } - return FALSE; + if (SkPaint::kStroke_Style != paint.getStyle()) + return FALSE; + FXSYS_assert(coverage); + SkScalar strokeWidth = paint.getStrokeWidth(); + if (0 == strokeWidth) { + *coverage = SK_Scalar1; + return TRUE; + } + // if we get here, we need to try to fake a thick-stroke with a modulated + // hairline + if (!paint.isAntiAlias()) + return FALSE; + if (strokeWidth <= SK_Scalar1) { + *coverage = strokeWidth; + return TRUE; + } + return FALSE; } -void SuperBlitter_skia::DrawPath(const SkPath& srcPath, SkBlitter* blitter, const SkRasterClip& rect, const SkPaint& origPaint) -{ - SkPath* pathPtr = (SkPath*)&srcPath; - bool doFill = true; - SkPath tmpPath; - SkTCopyOnFirstWrite paint(origPaint); - { - SkScalar coverage; - if (FxSkDrawTreatAsHairline(origPaint, &coverage)) { - if (SK_Scalar1 == coverage) { - paint.writable()->setStrokeWidth(0); - } else if (1) {//xfermodeSupportsCoverageAsAlpha(xfer), we not use blend mode here, xfer aways NULL. - U8CPU newAlpha; - // this is the old technique, which we preserve for now so - // we don't change previous results (testing) - // the new way seems fine, its just (a tiny bit) different - int scale = (int)SkScalarMul(coverage, 256); - newAlpha = origPaint.getAlpha() * scale >> 8; - SkPaint* writablePaint = paint.writable(); - writablePaint->setStrokeWidth(0); - writablePaint->setAlpha(newAlpha); - } - } - } - if (paint->getPathEffect() || paint->getStyle() != SkPaint::kFill_Style) { - SkIRect devBounds = rect.getBounds(); - // outset to have slop for antialasing and hairlines - devBounds.outset(1, 1); - SkRect cullRect = SkRect::Make(devBounds); - doFill = paint->getFillPath(*pathPtr, &tmpPath, &cullRect); - pathPtr = &tmpPath; - } - // avoid possibly allocating a new path in transform if we can - SkPath* devPathPtr = pathPtr; - void (*proc)(const SkPath&, const SkRasterClip&, SkBlitter*); - if (doFill) { - if (paint->isAntiAlias()) { - proc = SkScan::AntiFillPath; - } else { - proc = SkScan::FillPath; - } - } else { // hairline - if (paint->isAntiAlias()) { - proc = SkScan::AntiHairPath; - } else { - proc = SkScan::HairPath; - } - } - proc(*devPathPtr, rect, blitter); +void SuperBlitter_skia::DrawPath(const SkPath& srcPath, + SkBlitter* blitter, + const SkRasterClip& rect, + const SkPaint& origPaint) { + SkPath* pathPtr = (SkPath*)&srcPath; + bool doFill = true; + SkPath tmpPath; + SkTCopyOnFirstWrite paint(origPaint); + { + SkScalar coverage; + if (FxSkDrawTreatAsHairline(origPaint, &coverage)) { + if (SK_Scalar1 == coverage) { + paint.writable()->setStrokeWidth(0); + } else if (1) { // xfermodeSupportsCoverageAsAlpha(xfer), we not use + // blend mode here, xfer aways NULL. + U8CPU newAlpha; + // this is the old technique, which we preserve for now so + // we don't change previous results (testing) + // the new way seems fine, its just (a tiny bit) different + int scale = (int)SkScalarMul(coverage, 256); + newAlpha = origPaint.getAlpha() * scale >> 8; + SkPaint* writablePaint = paint.writable(); + writablePaint->setStrokeWidth(0); + writablePaint->setAlpha(newAlpha); + } + } + } + if (paint->getPathEffect() || paint->getStyle() != SkPaint::kFill_Style) { + SkIRect devBounds = rect.getBounds(); + // outset to have slop for antialasing and hairlines + devBounds.outset(1, 1); + SkRect cullRect = SkRect::Make(devBounds); + doFill = paint->getFillPath(*pathPtr, &tmpPath, &cullRect); + pathPtr = &tmpPath; + } + // avoid possibly allocating a new path in transform if we can + SkPath* devPathPtr = pathPtr; + void (*proc)(const SkPath&, const SkRasterClip&, SkBlitter*); + if (doFill) { + if (paint->isAntiAlias()) { + proc = SkScan::AntiFillPath; + } else { + proc = SkScan::FillPath; + } + } else { // hairline + if (paint->isAntiAlias()) { + proc = SkScan::AntiHairPath; + } else { + proc = SkScan::HairPath; + } + } + proc(*devPathPtr, rect, blitter); } -class CSkia_PathData -{ -public: - CSkia_PathData() {} - ~CSkia_PathData() {} - SkPath m_PathData; +class CSkia_PathData { + public: + CSkia_PathData() {} + ~CSkia_PathData() {} + SkPath m_PathData; - void BuildPath(const CFX_PathData* pPathData, const CFX_AffineMatrix* pObject2Device); + void BuildPath(const CFX_PathData* pPathData, + const CFX_AffineMatrix* pObject2Device); }; -void CSkia_PathData::BuildPath(const CFX_PathData* pPathData, const CFX_AffineMatrix* pObject2Device) -{ - const CFX_PathData* pFPath = pPathData; - int nPoints = pFPath->GetPointCount(); - FX_PATHPOINT* pPoints = pFPath->GetPoints(); - for (int i = 0; i < nPoints; i ++) { - FX_FIXFLOAT x = pPoints[i].m_PointX, y = pPoints[i].m_PointY; - if (pObject2Device) pObject2Device->Transform(x, y); - int point_type = pPoints[i].m_Flag & FXPT_TYPE; - if (point_type == FXPT_MOVETO) { - m_PathData.moveTo(x, y); - } else if (point_type == FXPT_LINETO) { - if (pPoints[i-1].m_Flag == FXPT_MOVETO && (i == nPoints-1 || pPoints[i+1].m_Flag == FXPT_MOVETO) && - FXSYS_abs(pPoints[i].m_PointX - pPoints[i-1].m_PointX) < 0.4f && FXSYS_abs(pPoints[i].m_PointY - pPoints[i-1].m_PointY)< 0.4f) - // PDF line includes the destination point, unlike Windows line. - // We received some PDF which actually draws zero length lines. TESTDOC: summer cha show.pdf - // Therefore, we have to extend the line by 0.4 pixel here. - // But only for standalone segment. TESTDOC: bug #1434 - maze.pdf; TESTDOC: bug#1508 di704P_QIG_111.pdf - x += 0.4; - // TODO: we should actually tell skia vertex generator to process zero length stroked line - // (only butts are drawn) - m_PathData.lineTo(x, y); - } else if (point_type == FXPT_BEZIERTO) { - FX_FIXFLOAT x2 = pPoints[i+1].m_PointX, y2 = pPoints[i+1].m_PointY; - FX_FIXFLOAT x3 = pPoints[i+2].m_PointX, y3 = pPoints[i+2].m_PointY; - if (pObject2Device){ - pObject2Device->Transform(x2, y2); - pObject2Device->Transform(x3, y3); - } - m_PathData.cubicTo(x, y, x2, y2, x3, y3); - i += 2; - } - if (pPoints[i].m_Flag & FXPT_CLOSEFIGURE) m_PathData.close(); - } +void CSkia_PathData::BuildPath(const CFX_PathData* pPathData, + const CFX_AffineMatrix* pObject2Device) { + const CFX_PathData* pFPath = pPathData; + int nPoints = pFPath->GetPointCount(); + FX_PATHPOINT* pPoints = pFPath->GetPoints(); + for (int i = 0; i < nPoints; i++) { + FX_FIXFLOAT x = pPoints[i].m_PointX, y = pPoints[i].m_PointY; + if (pObject2Device) + pObject2Device->Transform(x, y); + int point_type = pPoints[i].m_Flag & FXPT_TYPE; + if (point_type == FXPT_MOVETO) { + m_PathData.moveTo(x, y); + } else if (point_type == FXPT_LINETO) { + if (pPoints[i - 1].m_Flag == FXPT_MOVETO && + (i == nPoints - 1 || pPoints[i + 1].m_Flag == FXPT_MOVETO) && + FXSYS_abs(pPoints[i].m_PointX - pPoints[i - 1].m_PointX) < 0.4f && + FXSYS_abs(pPoints[i].m_PointY - pPoints[i - 1].m_PointY) < 0.4f) + // PDF line includes the destination point, unlike Windows line. + // We received some PDF which actually draws zero length lines. TESTDOC: + // summer cha show.pdf + // Therefore, we have to extend the line by 0.4 pixel here. + // But only for standalone segment. TESTDOC: bug #1434 - maze.pdf; + // TESTDOC: bug#1508 di704P_QIG_111.pdf + x += 0.4; + // TODO: we should actually tell skia vertex generator to process zero + // length stroked line + // (only butts are drawn) + m_PathData.lineTo(x, y); + } else if (point_type == FXPT_BEZIERTO) { + FX_FIXFLOAT x2 = pPoints[i + 1].m_PointX, y2 = pPoints[i + 1].m_PointY; + FX_FIXFLOAT x3 = pPoints[i + 2].m_PointX, y3 = pPoints[i + 2].m_PointY; + if (pObject2Device) { + pObject2Device->Transform(x2, y2); + pObject2Device->Transform(x3, y3); + } + m_PathData.cubicTo(x, y, x2, y2, x3, y3); + i += 2; + } + if (pPoints[i].m_Flag & FXPT_CLOSEFIGURE) + m_PathData.close(); + } } // convert a stroking path to scanlines -static void SkRasterizeStroke(SkPaint& spaint, SkPath* dstPathData, SkPath& path_data, - const CFX_AffineMatrix* pObject2Device, - const CFX_GraphStateData* pGraphState, FX_FIXFLOAT scale = FIX8_ONE, - FX_BOOL bStrokeAdjust = FALSE, FX_BOOL bTextMode = FALSE) -{ - SkPaint::Cap cap; - switch (pGraphState->m_LineCap) { - case CFX_GraphStateData::LineCapRound: - cap = SkPaint::kRound_Cap; - break; - case CFX_GraphStateData::LineCapSquare: - cap = SkPaint::kSquare_Cap; - break; - default: - cap = SkPaint::kButt_Cap; - break; - } - SkPaint::Join join; - switch (pGraphState->m_LineJoin) { - case CFX_GraphStateData::LineJoinRound: - join = SkPaint::kRound_Join; - break; - case CFX_GraphStateData::LineJoinBevel: - join = SkPaint::kBevel_Join; - break; - default: - join = SkPaint::kMiter_Join; - break; - } - FX_FIXFLOAT width = pGraphState->m_LineWidth*scale; - FX_FIXFLOAT unit = fix32_to_8(fixdiv_8_8_to_32(FIX8_ONE, (pObject2Device->GetXUnit() + pObject2Device->GetYUnit()) / 2)); - if (width <= unit) width = unit; - - if (pGraphState->m_DashArray == NULL) { - SkStroke stroker; - stroker.setCap(cap); - stroker.setJoin(join); - stroker.setMiterLimit(pGraphState->m_MiterLimit); - stroker.setWidth(width); - stroker.setDoFill(FALSE); - stroker.strokePath(path_data, dstPathData); - SkMatrix smatrix; - smatrix.setAll(pObject2Device->a, pObject2Device->c, pObject2Device->e, pObject2Device->b, pObject2Device->d, pObject2Device->f, 0, 0, 1); - dstPathData->transform(smatrix); - } else { - int count = (pGraphState->m_DashCount+1)/2; - SkScalar* intervals = FX_Alloc2D(SkScalar, count, sizeof(SkScalar)); - // Set dash pattern - for (int i = 0; i < count; i ++) { - FX_FIXFLOAT on = pGraphState->m_DashArray[i*2]; - if (on <= 0.000001f) on = FIX8_ONE/10; - FX_FIXFLOAT off = i*2+1 == pGraphState->m_DashCount ? on : - pGraphState->m_DashArray[i*2+1]; - if (off < 0) off = 0; - intervals[i*2]=on*scale; - intervals[i*2+1]=off*scale; - } - SkDashPathEffect* pEffect = new SkDashPathEffect(intervals,count*2, pGraphState->m_DashPhase*scale); - spaint.setPathEffect(pEffect)->unref(); - spaint.setStrokeWidth(width); - spaint.setStrokeMiter(pGraphState->m_MiterLimit); - spaint.setStrokeCap(cap); - spaint.setStrokeJoin(join); - spaint.getFillPath(path_data, dstPathData); - SkMatrix smatrix; - smatrix.setAll(pObject2Device->a, pObject2Device->c, pObject2Device->e, pObject2Device->b, pObject2Device->d, pObject2Device->f, 0, 0, 1); - dstPathData->transform(smatrix); - FX_Free(intervals); - } +static void SkRasterizeStroke(SkPaint& spaint, + SkPath* dstPathData, + SkPath& path_data, + const CFX_AffineMatrix* pObject2Device, + const CFX_GraphStateData* pGraphState, + FX_FIXFLOAT scale = FIX8_ONE, + FX_BOOL bStrokeAdjust = FALSE, + FX_BOOL bTextMode = FALSE) { + SkPaint::Cap cap; + switch (pGraphState->m_LineCap) { + case CFX_GraphStateData::LineCapRound: + cap = SkPaint::kRound_Cap; + break; + case CFX_GraphStateData::LineCapSquare: + cap = SkPaint::kSquare_Cap; + break; + default: + cap = SkPaint::kButt_Cap; + break; + } + SkPaint::Join join; + switch (pGraphState->m_LineJoin) { + case CFX_GraphStateData::LineJoinRound: + join = SkPaint::kRound_Join; + break; + case CFX_GraphStateData::LineJoinBevel: + join = SkPaint::kBevel_Join; + break; + default: + join = SkPaint::kMiter_Join; + break; + } + FX_FIXFLOAT width = pGraphState->m_LineWidth * scale; + FX_FIXFLOAT unit = fix32_to_8(fixdiv_8_8_to_32( + FIX8_ONE, (pObject2Device->GetXUnit() + pObject2Device->GetYUnit()) / 2)); + if (width <= unit) + width = unit; + + if (pGraphState->m_DashArray == NULL) { + SkStroke stroker; + stroker.setCap(cap); + stroker.setJoin(join); + stroker.setMiterLimit(pGraphState->m_MiterLimit); + stroker.setWidth(width); + stroker.setDoFill(FALSE); + stroker.strokePath(path_data, dstPathData); + SkMatrix smatrix; + smatrix.setAll(pObject2Device->a, pObject2Device->c, pObject2Device->e, + pObject2Device->b, pObject2Device->d, pObject2Device->f, 0, + 0, 1); + dstPathData->transform(smatrix); + } else { + int count = (pGraphState->m_DashCount + 1) / 2; + SkScalar* intervals = FX_Alloc2D(SkScalar, count, sizeof(SkScalar)); + // Set dash pattern + for (int i = 0; i < count; i++) { + FX_FIXFLOAT on = pGraphState->m_DashArray[i * 2]; + if (on <= 0.000001f) + on = FIX8_ONE / 10; + FX_FIXFLOAT off = i * 2 + 1 == pGraphState->m_DashCount + ? on + : pGraphState->m_DashArray[i * 2 + 1]; + if (off < 0) + off = 0; + intervals[i * 2] = on * scale; + intervals[i * 2 + 1] = off * scale; + } + SkDashPathEffect* pEffect = new SkDashPathEffect( + intervals, count * 2, pGraphState->m_DashPhase * scale); + spaint.setPathEffect(pEffect)->unref(); + spaint.setStrokeWidth(width); + spaint.setStrokeMiter(pGraphState->m_MiterLimit); + spaint.setStrokeCap(cap); + spaint.setStrokeJoin(join); + spaint.getFillPath(path_data, dstPathData); + SkMatrix smatrix; + smatrix.setAll(pObject2Device->a, pObject2Device->c, pObject2Device->e, + pObject2Device->b, pObject2Device->d, pObject2Device->f, 0, + 0, 1); + dstPathData->transform(smatrix); + FX_Free(intervals); + } } -CFX_SkiaDeviceDriver::CFX_SkiaDeviceDriver(CFX_DIBitmap* pBitmap, int dither_bits, FX_BOOL bRgbByteOrder, CFX_DIBitmap* pOriDevice, FX_BOOL bGroupKnockout) -{ - m_pAggDriver = new CFX_AggDeviceDriver(pBitmap, dither_bits, bRgbByteOrder, pOriDevice, bGroupKnockout); +CFX_SkiaDeviceDriver::CFX_SkiaDeviceDriver(CFX_DIBitmap* pBitmap, + int dither_bits, + FX_BOOL bRgbByteOrder, + CFX_DIBitmap* pOriDevice, + FX_BOOL bGroupKnockout) { + m_pAggDriver = new CFX_AggDeviceDriver(pBitmap, dither_bits, bRgbByteOrder, + pOriDevice, bGroupKnockout); } -CFX_SkiaDeviceDriver::~CFX_SkiaDeviceDriver() -{ - delete m_pAggDriver; +CFX_SkiaDeviceDriver::~CFX_SkiaDeviceDriver() { + delete m_pAggDriver; } -FX_BOOL CFX_SkiaDeviceDriver::DrawDeviceText(int nChars, const FXTEXT_CHARPOS* pCharPos, CFX_Font* pFont, - CFX_FontCache* pCache, const CFX_AffineMatrix* pObject2Device, FX_FIXFLOAT font_size, FX_DWORD color, - int alpha_flag, void* pIccTransform) -{ - return m_pAggDriver->DrawDeviceText(nChars, pCharPos, pFont,pCache, pObject2Device, font_size, color, - alpha_flag, pIccTransform); +FX_BOOL CFX_SkiaDeviceDriver::DrawDeviceText( + int nChars, + const FXTEXT_CHARPOS* pCharPos, + CFX_Font* pFont, + CFX_FontCache* pCache, + const CFX_AffineMatrix* pObject2Device, + FX_FIXFLOAT font_size, + FX_DWORD color, + int alpha_flag, + void* pIccTransform) { + return m_pAggDriver->DrawDeviceText(nChars, pCharPos, pFont, pCache, + pObject2Device, font_size, color, + alpha_flag, pIccTransform); } -int CFX_SkiaDeviceDriver::GetDeviceCaps(int caps_id) -{ - return m_pAggDriver->GetDeviceCaps(caps_id); +int CFX_SkiaDeviceDriver::GetDeviceCaps(int caps_id) { + return m_pAggDriver->GetDeviceCaps(caps_id); } -void CFX_SkiaDeviceDriver::SaveState() -{ - m_pAggDriver->SaveState(); +void CFX_SkiaDeviceDriver::SaveState() { + m_pAggDriver->SaveState(); } -void CFX_SkiaDeviceDriver::RestoreState(FX_BOOL bKeepSaved) -{ - m_pAggDriver->RestoreState(bKeepSaved); +void CFX_SkiaDeviceDriver::RestoreState(FX_BOOL bKeepSaved) { + m_pAggDriver->RestoreState(bKeepSaved); } -void CFX_SkiaDeviceDriver::SetClipMask(rasterizer_scanline_aa& rasterizer) -{ - m_pAggDriver->SetClipMask(rasterizer); +void CFX_SkiaDeviceDriver::SetClipMask(rasterizer_scanline_aa& rasterizer) { + m_pAggDriver->SetClipMask(rasterizer); } -void CFX_SkiaDeviceDriver::SetClipMask(SkPath& skPath, SkPaint* spaint) -{ - SkIRect clip_box; - clip_box.set(0, 0, fix0_to_8(GetDeviceCaps(FXDC_PIXEL_WIDTH)), fix0_to_8(GetDeviceCaps(FXDC_PIXEL_HEIGHT))); - clip_box.intersect(m_pAggDriver->m_pClipRgn->GetBox().left, m_pAggDriver->m_pClipRgn->GetBox().top, - m_pAggDriver->m_pClipRgn->GetBox().right, m_pAggDriver->m_pClipRgn->GetBox().bottom); - - SkPath* pathPtr = &skPath; - - SkRect path_rect = skPath.getBounds(); - - clip_box.intersect(FXSYS_floor(path_rect.fLeft), FXSYS_floor(path_rect.fTop), FXSYS_floor(path_rect.fRight)+1, FXSYS_floor(path_rect.fBottom)+1); - CFX_DIBitmapRef mask; - CFX_DIBitmap* pThisLayer = mask.New(); - pThisLayer->Create(clip_box.width(), clip_box.height(), FXDIB_8bppMask); - pThisLayer->Clear(0); - - CFX_SkiaA8Renderer render; - render.Init(pThisLayer, clip_box.fLeft, clip_box.fTop); - - SkRasterClip rasterClip(clip_box); - SuperBlitter_skia::DrawPath(skPath, (SkBlitter*)&render, rasterClip, *spaint); - - // Finally, we have got the mask that we need, intersect with current clip region - m_pAggDriver->m_pClipRgn->IntersectMaskF(clip_box.fLeft, clip_box.fTop, mask); - +void CFX_SkiaDeviceDriver::SetClipMask(SkPath& skPath, SkPaint* spaint) { + SkIRect clip_box; + clip_box.set(0, 0, fix0_to_8(GetDeviceCaps(FXDC_PIXEL_WIDTH)), + fix0_to_8(GetDeviceCaps(FXDC_PIXEL_HEIGHT))); + clip_box.intersect(m_pAggDriver->m_pClipRgn->GetBox().left, + m_pAggDriver->m_pClipRgn->GetBox().top, + m_pAggDriver->m_pClipRgn->GetBox().right, + m_pAggDriver->m_pClipRgn->GetBox().bottom); + + SkPath* pathPtr = &skPath; + + SkRect path_rect = skPath.getBounds(); + + clip_box.intersect(FXSYS_floor(path_rect.fLeft), FXSYS_floor(path_rect.fTop), + FXSYS_floor(path_rect.fRight) + 1, + FXSYS_floor(path_rect.fBottom) + 1); + CFX_DIBitmapRef mask; + CFX_DIBitmap* pThisLayer = mask.New(); + pThisLayer->Create(clip_box.width(), clip_box.height(), FXDIB_8bppMask); + pThisLayer->Clear(0); + + CFX_SkiaA8Renderer render; + render.Init(pThisLayer, clip_box.fLeft, clip_box.fTop); + + SkRasterClip rasterClip(clip_box); + SuperBlitter_skia::DrawPath(skPath, (SkBlitter*)&render, rasterClip, *spaint); + + // Finally, we have got the mask that we need, intersect with current clip + // region + m_pAggDriver->m_pClipRgn->IntersectMaskF(clip_box.fLeft, clip_box.fTop, mask); } -FX_BOOL CFX_SkiaDeviceDriver::SetClip_PathFill(const CFX_PathData* pPathData, // path info - const CFX_AffineMatrix* pObject2Device, // optional transformation - int fill_mode // fill mode, WINDING or ALTERNATE - ) -{ - if (m_pAggDriver->m_pClipRgn == NULL) - m_pAggDriver->m_pClipRgn = new CFX_ClipRgn(GetDeviceCaps(FXDC_PIXEL_WIDTH), GetDeviceCaps(FXDC_PIXEL_HEIGHT)); - - if (pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) { - CFX_FloatRect rectf; - if (pPathData->IsRect(pObject2Device, &rectf)) { - rectf.Intersect(CFX_FloatRect(0, 0, (FX_FIXFLOAT)GetDeviceCaps(FXDC_PIXEL_WIDTH), (FX_FIXFLOAT)GetDeviceCaps(FXDC_PIXEL_HEIGHT))); - FX_RECT rect = rectf.GetOutterRect(); - m_pAggDriver->m_pClipRgn->IntersectRect(rect); - return TRUE; - } - } - CSkia_PathData path_data; - path_data.BuildPath(pPathData, pObject2Device); - path_data.m_PathData.close(); - path_data.m_PathData.setFillType((fill_mode&3) == FXFILL_WINDING? SkPath::kWinding_FillType:SkPath::kEvenOdd_FillType); - - SkPaint spaint; - spaint.setColor(0xffffffff); - spaint.setAntiAlias(TRUE); - spaint.setStyle(SkPaint::kFill_Style); - - SetClipMask(path_data.m_PathData, &spaint); - - return TRUE; +FX_BOOL CFX_SkiaDeviceDriver::SetClip_PathFill( + const CFX_PathData* pPathData, // path info + const CFX_AffineMatrix* pObject2Device, // optional transformation + int fill_mode // fill mode, WINDING or ALTERNATE + ) { + if (m_pAggDriver->m_pClipRgn == NULL) + m_pAggDriver->m_pClipRgn = new CFX_ClipRgn( + GetDeviceCaps(FXDC_PIXEL_WIDTH), GetDeviceCaps(FXDC_PIXEL_HEIGHT)); + + if (pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) { + CFX_FloatRect rectf; + if (pPathData->IsRect(pObject2Device, &rectf)) { + rectf.Intersect( + CFX_FloatRect(0, 0, (FX_FIXFLOAT)GetDeviceCaps(FXDC_PIXEL_WIDTH), + (FX_FIXFLOAT)GetDeviceCaps(FXDC_PIXEL_HEIGHT))); + FX_RECT rect = rectf.GetOutterRect(); + m_pAggDriver->m_pClipRgn->IntersectRect(rect); + return TRUE; + } + } + CSkia_PathData path_data; + path_data.BuildPath(pPathData, pObject2Device); + path_data.m_PathData.close(); + path_data.m_PathData.setFillType((fill_mode & 3) == FXFILL_WINDING + ? SkPath::kWinding_FillType + : SkPath::kEvenOdd_FillType); + + SkPaint spaint; + spaint.setColor(0xffffffff); + spaint.setAntiAlias(TRUE); + spaint.setStyle(SkPaint::kFill_Style); + + SetClipMask(path_data.m_PathData, &spaint); + + return TRUE; } -FX_BOOL CFX_SkiaDeviceDriver::SetClip_PathStroke(const CFX_PathData* pPathData, // path info - const CFX_AffineMatrix* pObject2Device, // optional transformation - const CFX_GraphStateData* pGraphState // graphic state, for pen attributes - ) -{ - if (m_pAggDriver->m_pClipRgn == NULL) - m_pAggDriver->m_pClipRgn = new CFX_ClipRgn(GetDeviceCaps(FXDC_PIXEL_WIDTH), GetDeviceCaps(FXDC_PIXEL_HEIGHT)); - - // build path data - CSkia_PathData path_data; - path_data.BuildPath(pPathData, NULL); - path_data.m_PathData.setFillType(SkPath::kWinding_FillType); - - SkPaint spaint; - spaint.setColor(0xffffffff); - spaint.setStyle(SkPaint::kStroke_Style); - spaint.setAntiAlias(TRUE); - - SkPath dst_path; - SkRasterizeStroke(spaint, &dst_path, path_data.m_PathData, pObject2Device, pGraphState, 1, FALSE, 0); - spaint.setStyle(SkPaint::kFill_Style); - SetClipMask(dst_path, &spaint); - - return TRUE; +FX_BOOL CFX_SkiaDeviceDriver::SetClip_PathStroke( + const CFX_PathData* pPathData, // path info + const CFX_AffineMatrix* pObject2Device, // optional transformation + const CFX_GraphStateData* pGraphState // graphic state, for pen attributes + ) { + if (m_pAggDriver->m_pClipRgn == NULL) + m_pAggDriver->m_pClipRgn = new CFX_ClipRgn( + GetDeviceCaps(FXDC_PIXEL_WIDTH), GetDeviceCaps(FXDC_PIXEL_HEIGHT)); + + // build path data + CSkia_PathData path_data; + path_data.BuildPath(pPathData, NULL); + path_data.m_PathData.setFillType(SkPath::kWinding_FillType); + + SkPaint spaint; + spaint.setColor(0xffffffff); + spaint.setStyle(SkPaint::kStroke_Style); + spaint.setAntiAlias(TRUE); + + SkPath dst_path; + SkRasterizeStroke(spaint, &dst_path, path_data.m_PathData, pObject2Device, + pGraphState, 1, FALSE, 0); + spaint.setStyle(SkPaint::kFill_Style); + SetClipMask(dst_path, &spaint); + + return TRUE; } -FX_BOOL CFX_SkiaDeviceDriver::RenderRasterizer(rasterizer_scanline_aa& rasterizer, FX_DWORD color, FX_BOOL bFullCover, FX_BOOL bGroupKnockout, - int alpha_flag, void* pIccTransform) -{ - return m_pAggDriver->RenderRasterizer(rasterizer, color, bFullCover, bGroupKnockout,alpha_flag, pIccTransform); +FX_BOOL CFX_SkiaDeviceDriver::RenderRasterizer( + rasterizer_scanline_aa& rasterizer, + FX_DWORD color, + FX_BOOL bFullCover, + FX_BOOL bGroupKnockout, + int alpha_flag, + void* pIccTransform) { + return m_pAggDriver->RenderRasterizer( + rasterizer, color, bFullCover, bGroupKnockout, alpha_flag, pIccTransform); } -FX_BOOL CFX_SkiaDeviceDriver::RenderRasterizerSkia(SkPath& skPath, const SkPaint& origPaint, SkIRect& rect, FX_DWORD color, FX_BOOL bFullCover, FX_BOOL bGroupKnockout, - int alpha_flag, void* pIccTransform, FX_BOOL bFill) -{ - CFX_DIBitmap* pt = bGroupKnockout?m_pAggDriver->GetBackDrop():NULL; - CFX_SkiaRenderer render; - if (!render.Init(m_pAggDriver->m_pBitmap, pt, m_pAggDriver->m_pClipRgn, color, bFullCover, m_pAggDriver->m_bRgbByteOrder, alpha_flag, pIccTransform)) - return FALSE; - - SkRasterClip rasterClip(rect); - SuperBlitter_skia::DrawPath(skPath, (SkBlitter*)&render, rasterClip, origPaint); - - return TRUE; - +FX_BOOL CFX_SkiaDeviceDriver::RenderRasterizerSkia(SkPath& skPath, + const SkPaint& origPaint, + SkIRect& rect, + FX_DWORD color, + FX_BOOL bFullCover, + FX_BOOL bGroupKnockout, + int alpha_flag, + void* pIccTransform, + FX_BOOL bFill) { + CFX_DIBitmap* pt = bGroupKnockout ? m_pAggDriver->GetBackDrop() : NULL; + CFX_SkiaRenderer render; + if (!render.Init(m_pAggDriver->m_pBitmap, pt, m_pAggDriver->m_pClipRgn, color, + bFullCover, m_pAggDriver->m_bRgbByteOrder, alpha_flag, + pIccTransform)) + return FALSE; + + SkRasterClip rasterClip(rect); + SuperBlitter_skia::DrawPath(skPath, (SkBlitter*)&render, rasterClip, + origPaint); + + return TRUE; } -FX_BOOL CFX_SkiaDeviceDriver::DrawPath(const CFX_PathData* pPathData, // path info - const CFX_AffineMatrix* pObject2Device, // optional transformation - const CFX_GraphStateData* pGraphState, // graphic state, for pen attributes - FX_DWORD fill_color, // fill color - FX_DWORD stroke_color, // stroke color - int fill_mode, // fill mode, WINDING or ALTERNATE. 0 for not filled - int alpha_flag, - void* pIccTransform - ) -{ - if (GetBuffer() == NULL) return TRUE; - FOXIT_DEBUG1("CFX_SkiaDeviceDriver::DrawPath: entering"); - SkIRect rect; - rect.set(0, 0, GetDeviceCaps(FXDC_PIXEL_WIDTH), GetDeviceCaps(FXDC_PIXEL_HEIGHT)); - if ((fill_mode & 3) && fill_color) { - // We have to transform before building path data, otherwise we'll have flatting problem - // when we enlarge a small path (flatten before transformed) - // TESTDOC: Bug #5115 - DS_S1Dimpact_lr.pdf - // build path data - CSkia_PathData path_data; - path_data.BuildPath(pPathData, pObject2Device); - //path_data.m_PathData.close(); - path_data.m_PathData.setFillType((fill_mode&3) == FXFILL_WINDING? SkPath::kWinding_FillType:SkPath::kEvenOdd_FillType); - - SkPaint spaint; - spaint.setAntiAlias(TRUE); - spaint.setStyle(SkPaint::kFill_Style); - spaint.setColor(fill_color); - if (!RenderRasterizerSkia(path_data.m_PathData, spaint, rect, fill_color, fill_mode & FXFILL_FULLCOVER, FALSE, alpha_flag, pIccTransform)) - return FALSE; - } - - int stroke_alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_STROKE(alpha_flag) : FXARGB_A(stroke_color); - - if (pGraphState && stroke_alpha) { - // We split the matrix into two parts: first part doing the scaling, so we won't have the - // flatness problem, second part doing the transformation, so we don't have stroking geo problem. - // TESTDOC: Bug #5253 - test[1].pdf - CFX_AffineMatrix matrix1, matrix2; - if (pObject2Device) { - matrix1.a = FXSYS_fabs(pObject2Device->a) > FXSYS_fabs(pObject2Device->b) ? - FXSYS_fabs(pObject2Device->a) : FXSYS_fabs(pObject2Device->b); - matrix1.d = matrix1.a;//FXSYS_fabs(pObject2Device->c) > FXSYS_fabs(pObject2Device->d) ? - //pObject2Device->c : pObject2Device->d; - matrix2.Set(pObject2Device->a/matrix1.a, pObject2Device->b/matrix1.a, - pObject2Device->c/matrix1.d, pObject2Device->d/matrix1.d, - pObject2Device->e, pObject2Device->f); - } - // build path data - CSkia_PathData path_data; - path_data.BuildPath(pPathData, &matrix1); - path_data.m_PathData.setFillType(SkPath::kWinding_FillType); - - SkPaint spaint; - spaint.setColor(stroke_color); - spaint.setStyle(SkPaint::kStroke_Style); - spaint.setAntiAlias(TRUE); - SkPath dst_path; - SkRasterizeStroke(spaint, &dst_path, path_data.m_PathData, &matrix2, pGraphState, matrix1.a, FALSE, 0); - spaint.setStyle(SkPaint::kFill_Style); - int fill_flag = FXGETFLAG_COLORTYPE(alpha_flag)<<8 | FXGETFLAG_ALPHA_STROKE(alpha_flag); - - if (!RenderRasterizerSkia(dst_path, spaint, rect, stroke_color, fill_mode & FXFILL_FULLCOVER, FALSE, fill_flag, pIccTransform, FALSE)) - return FALSE; - - } - - return TRUE; +FX_BOOL CFX_SkiaDeviceDriver::DrawPath( + const CFX_PathData* pPathData, // path info + const CFX_AffineMatrix* pObject2Device, // optional transformation + const CFX_GraphStateData* pGraphState, // graphic state, for pen attributes + FX_DWORD fill_color, // fill color + FX_DWORD stroke_color, // stroke color + int fill_mode, // fill mode, WINDING or ALTERNATE. 0 for not filled + int alpha_flag, + void* pIccTransform) { + if (GetBuffer() == NULL) + return TRUE; + FOXIT_DEBUG1("CFX_SkiaDeviceDriver::DrawPath: entering"); + SkIRect rect; + rect.set(0, 0, GetDeviceCaps(FXDC_PIXEL_WIDTH), + GetDeviceCaps(FXDC_PIXEL_HEIGHT)); + if ((fill_mode & 3) && fill_color) { + // We have to transform before building path data, otherwise we'll have + // flatting problem + // when we enlarge a small path (flatten before transformed) + // TESTDOC: Bug #5115 - DS_S1Dimpact_lr.pdf + // build path data + CSkia_PathData path_data; + path_data.BuildPath(pPathData, pObject2Device); + // path_data.m_PathData.close(); + path_data.m_PathData.setFillType((fill_mode & 3) == FXFILL_WINDING + ? SkPath::kWinding_FillType + : SkPath::kEvenOdd_FillType); + + SkPaint spaint; + spaint.setAntiAlias(TRUE); + spaint.setStyle(SkPaint::kFill_Style); + spaint.setColor(fill_color); + if (!RenderRasterizerSkia(path_data.m_PathData, spaint, rect, fill_color, + fill_mode & FXFILL_FULLCOVER, FALSE, alpha_flag, + pIccTransform)) + return FALSE; + } + + int stroke_alpha = FXGETFLAG_COLORTYPE(alpha_flag) + ? FXGETFLAG_ALPHA_STROKE(alpha_flag) + : FXARGB_A(stroke_color); + + if (pGraphState && stroke_alpha) { + // We split the matrix into two parts: first part doing the scaling, so we + // won't have the + // flatness problem, second part doing the transformation, so we don't have + // stroking geo problem. + // TESTDOC: Bug #5253 - test[1].pdf + CFX_AffineMatrix matrix1, matrix2; + if (pObject2Device) { + matrix1.a = FXSYS_fabs(pObject2Device->a) > FXSYS_fabs(pObject2Device->b) + ? FXSYS_fabs(pObject2Device->a) + : FXSYS_fabs(pObject2Device->b); + matrix1.d = matrix1.a; // FXSYS_fabs(pObject2Device->c) > + // FXSYS_fabs(pObject2Device->d) ? + // pObject2Device->c : pObject2Device->d; + matrix2.Set(pObject2Device->a / matrix1.a, pObject2Device->b / matrix1.a, + pObject2Device->c / matrix1.d, pObject2Device->d / matrix1.d, + pObject2Device->e, pObject2Device->f); + } + // build path data + CSkia_PathData path_data; + path_data.BuildPath(pPathData, &matrix1); + path_data.m_PathData.setFillType(SkPath::kWinding_FillType); + + SkPaint spaint; + spaint.setColor(stroke_color); + spaint.setStyle(SkPaint::kStroke_Style); + spaint.setAntiAlias(TRUE); + SkPath dst_path; + SkRasterizeStroke(spaint, &dst_path, path_data.m_PathData, &matrix2, + pGraphState, matrix1.a, FALSE, 0); + spaint.setStyle(SkPaint::kFill_Style); + int fill_flag = FXGETFLAG_COLORTYPE(alpha_flag) << 8 | + FXGETFLAG_ALPHA_STROKE(alpha_flag); + + if (!RenderRasterizerSkia(dst_path, spaint, rect, stroke_color, + fill_mode & FXFILL_FULLCOVER, FALSE, fill_flag, + pIccTransform, FALSE)) + return FALSE; + } + + return TRUE; } -FX_BOOL CFX_SkiaDeviceDriver::SetPixel(int x, int y, FX_DWORD color, - int alpha_flag, void* pIccTransform) -{ - return m_pAggDriver->SetPixel(x, y, color, alpha_flag, pIccTransform); +FX_BOOL CFX_SkiaDeviceDriver::SetPixel(int x, + int y, + FX_DWORD color, + int alpha_flag, + void* pIccTransform) { + return m_pAggDriver->SetPixel(x, y, color, alpha_flag, pIccTransform); } -FX_BOOL CFX_SkiaDeviceDriver::FillRect(const FX_RECT* pRect, FX_DWORD fill_color, int alpha_flag, void* pIccTransform) -{ - return m_pAggDriver->FillRect(pRect, fill_color, alpha_flag, pIccTransform); +FX_BOOL CFX_SkiaDeviceDriver::FillRect(const FX_RECT* pRect, + FX_DWORD fill_color, + int alpha_flag, + void* pIccTransform) { + return m_pAggDriver->FillRect(pRect, fill_color, alpha_flag, pIccTransform); } -FX_BOOL CFX_SkiaDeviceDriver::GetClipBox(FX_RECT* pRect) -{ - return m_pAggDriver->GetClipBox(pRect); +FX_BOOL CFX_SkiaDeviceDriver::GetClipBox(FX_RECT* pRect) { + return m_pAggDriver->GetClipBox(pRect); } -FX_BOOL CFX_SkiaDeviceDriver::GetDIBits(CFX_DIBitmap* pBitmap, int left, int top, void* pIccTransform, FX_BOOL bDEdge) -{ - return m_pAggDriver->GetDIBits(pBitmap, left, top, pIccTransform, bDEdge); +FX_BOOL CFX_SkiaDeviceDriver::GetDIBits(CFX_DIBitmap* pBitmap, + int left, + int top, + void* pIccTransform, + FX_BOOL bDEdge) { + return m_pAggDriver->GetDIBits(pBitmap, left, top, pIccTransform, bDEdge); } -FX_BOOL CFX_SkiaDeviceDriver::SetDIBits(const CFX_DIBSource* pBitmap, FX_DWORD argb, const FX_RECT* pSrcRect, int left, int top, int blend_type, - int alpha_flag, void* pIccTransform) -{ - return m_pAggDriver->SetDIBits(pBitmap, argb, pSrcRect, left, top, blend_type, alpha_flag, pIccTransform); +FX_BOOL CFX_SkiaDeviceDriver::SetDIBits(const CFX_DIBSource* pBitmap, + FX_DWORD argb, + const FX_RECT* pSrcRect, + int left, + int top, + int blend_type, + int alpha_flag, + void* pIccTransform) { + return m_pAggDriver->SetDIBits(pBitmap, argb, pSrcRect, left, top, blend_type, + alpha_flag, pIccTransform); } -FX_BOOL CFX_SkiaDeviceDriver::StretchDIBits(const CFX_DIBSource* pSource, FX_DWORD argb, int dest_left, int dest_top, - int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags, - int alpha_flag, void* pIccTransform) -{ - return m_pAggDriver->StretchDIBits(pSource, argb, dest_left, dest_top, - dest_width, dest_height, pClipRect, flags, - alpha_flag, pIccTransform); +FX_BOOL CFX_SkiaDeviceDriver::StretchDIBits(const CFX_DIBSource* pSource, + FX_DWORD argb, + int dest_left, + int dest_top, + int dest_width, + int dest_height, + const FX_RECT* pClipRect, + FX_DWORD flags, + int alpha_flag, + void* pIccTransform) { + return m_pAggDriver->StretchDIBits(pSource, argb, dest_left, dest_top, + dest_width, dest_height, pClipRect, flags, + alpha_flag, pIccTransform); } -FX_BOOL CFX_SkiaDeviceDriver::StartDIBits(const CFX_DIBSource* pSource, int bitmap_alpha, FX_DWORD argb, - const CFX_AffineMatrix* pMatrix, FX_DWORD render_flags, void*& handle, - int alpha_flag, void* pIccTransform) -{ - return m_pAggDriver->StartDIBits(pSource, bitmap_alpha, argb, - pMatrix, render_flags, handle, alpha_flag, pIccTransform); +FX_BOOL CFX_SkiaDeviceDriver::StartDIBits(const CFX_DIBSource* pSource, + int bitmap_alpha, + FX_DWORD argb, + const CFX_AffineMatrix* pMatrix, + FX_DWORD render_flags, + void*& handle, + int alpha_flag, + void* pIccTransform) { + return m_pAggDriver->StartDIBits(pSource, bitmap_alpha, argb, pMatrix, + render_flags, handle, alpha_flag, + pIccTransform); } -FX_BOOL CFX_SkiaDeviceDriver::ContinueDIBits(void* pHandle, IFX_Pause* pPause) -{ - return m_pAggDriver->ContinueDIBits(pHandle, pPause); +FX_BOOL CFX_SkiaDeviceDriver::ContinueDIBits(void* pHandle, IFX_Pause* pPause) { + return m_pAggDriver->ContinueDIBits(pHandle, pPause); } -void CFX_SkiaDeviceDriver::CancelDIBits(void* pHandle) -{ - m_pAggDriver->CancelDIBits(pHandle); +void CFX_SkiaDeviceDriver::CancelDIBits(void* pHandle) { + m_pAggDriver->CancelDIBits(pHandle); } -CFX_SkiaDevice::CFX_SkiaDevice() -{ - m_bOwnedBitmap = FALSE; +CFX_SkiaDevice::CFX_SkiaDevice() { + m_bOwnedBitmap = FALSE; } -FX_BOOL CFX_SkiaDevice::Attach(CFX_DIBitmap* pBitmap, int dither_bits, FX_BOOL bRgbByteOrder, CFX_DIBitmap* pOriDevice, FX_BOOL bGroupKnockout) -{ - if (pBitmap == NULL) - return FALSE; - SetBitmap(pBitmap); - CFX_SkiaDeviceDriver* pDriver = new CFX_SkiaDeviceDriver(pBitmap, dither_bits, bRgbByteOrder, pOriDevice, bGroupKnockout); - SetDeviceDriver(pDriver); - return TRUE; +FX_BOOL CFX_SkiaDevice::Attach(CFX_DIBitmap* pBitmap, + int dither_bits, + FX_BOOL bRgbByteOrder, + CFX_DIBitmap* pOriDevice, + FX_BOOL bGroupKnockout) { + if (pBitmap == NULL) + return FALSE; + SetBitmap(pBitmap); + CFX_SkiaDeviceDriver* pDriver = new CFX_SkiaDeviceDriver( + pBitmap, dither_bits, bRgbByteOrder, pOriDevice, bGroupKnockout); + SetDeviceDriver(pDriver); + return TRUE; } -FX_BOOL CFX_SkiaDevice::Create(int width, int height, FXDIB_Format format, int dither_bits, CFX_DIBitmap* pOriDevice) -{ - m_bOwnedBitmap = TRUE; - CFX_DIBitmap* pBitmap = new CFX_DIBitmap; - if (!pBitmap->Create(width, height, format)) { - delete pBitmap; - return FALSE; - } - SetBitmap(pBitmap); - CFX_SkiaDeviceDriver* pDriver = new CFX_SkiaDeviceDriver(pBitmap, dither_bits, FALSE, pOriDevice, FALSE); - SetDeviceDriver(pDriver); - return TRUE; +FX_BOOL CFX_SkiaDevice::Create(int width, + int height, + FXDIB_Format format, + int dither_bits, + CFX_DIBitmap* pOriDevice) { + m_bOwnedBitmap = TRUE; + CFX_DIBitmap* pBitmap = new CFX_DIBitmap; + if (!pBitmap->Create(width, height, format)) { + delete pBitmap; + return FALSE; + } + SetBitmap(pBitmap); + CFX_SkiaDeviceDriver* pDriver = + new CFX_SkiaDeviceDriver(pBitmap, dither_bits, FALSE, pOriDevice, FALSE); + SetDeviceDriver(pDriver); + return TRUE; } -CFX_SkiaDevice::~CFX_SkiaDevice() -{ - if (m_bOwnedBitmap && GetBitmap()) delete GetBitmap(); +CFX_SkiaDevice::~CFX_SkiaDevice() { + if (m_bOwnedBitmap && GetBitmap()) + delete GetBitmap(); } #endif diff --git a/core/src/fxge/skia/fx_skia_device.h b/core/src/fxge/skia/fx_skia_device.h index ab51e51a33..1de829b783 100644 --- a/core/src/fxge/skia/fx_skia_device.h +++ b/core/src/fxge/skia/fx_skia_device.h @@ -6,85 +6,141 @@ #define CORE_SRC_FXGE_SKIA_FX_SKIA_DEVICE_H_ #if defined(_SKIA_SUPPORT_) -class CFX_SkiaDeviceDriver : public IFX_RenderDeviceDriver -{ -public: - CFX_SkiaDeviceDriver(CFX_DIBitmap* pBitmap, int dither_bits, FX_BOOL bRgbByteOrder, CFX_DIBitmap* pOriDevice, FX_BOOL bGroupKnockout); - virtual ~CFX_SkiaDeviceDriver(); - - /** Options */ - virtual int GetDeviceCaps(int caps_id); - - /** Save and restore all graphic states */ - virtual void SaveState(); - virtual void RestoreState(FX_BOOL bKeepSaved); - - /** Set clipping path using filled region */ - virtual FX_BOOL SetClip_PathFill(const CFX_PathData* pPathData, // path info - const CFX_AffineMatrix* pObject2Device, // optional transformation - int fill_mode // fill mode, WINDING or ALTERNATE - ); - - /** Set clipping path using stroked region */ - virtual FX_BOOL SetClip_PathStroke(const CFX_PathData* pPathData, // path info - const CFX_AffineMatrix* pObject2Device, // optional transformation - const CFX_GraphStateData* pGraphState // graphic state, for pen attributes - ); - - /** Draw a path */ - virtual FX_BOOL DrawPath(const CFX_PathData* pPathData, - const CFX_AffineMatrix* pObject2Device, - const CFX_GraphStateData* pGraphState, - FX_DWORD fill_color, - FX_DWORD stroke_color, - int fill_mode, - int alpha_flag = 0, - void* pIccTransform = NULL - ); - - virtual FX_BOOL SetPixel(int x, int y, FX_DWORD color, - int alpha_flag = 0, void* pIccTransform = NULL); - - virtual FX_BOOL FillRect(const FX_RECT* pRect, FX_DWORD fill_color, - int alpha_flag = 0, void* pIccTransform = NULL); - - /** Draw a single pixel (device dependant) line */ - virtual FX_BOOL DrawCosmeticLine(FX_FIXFLOAT x1, FX_FIXFLOAT y1, FX_FIXFLOAT x2, FX_FIXFLOAT y2, FX_DWORD color, - int alpha_flag, void* pIccTransform, int blend_type) { return FALSE; } - - virtual FX_BOOL GetClipBox(FX_RECT* pRect); - - /** Load device buffer into a DIB */ - virtual FX_BOOL GetDIBits(CFX_DIBitmap* pBitmap, int left, int top, void* pIccTransform = NULL, FX_BOOL bDEdge = FALSE); - - virtual CFX_DIBitmap* GetBackDrop() { return m_pAggDriver->GetBackDrop(); } - - virtual FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, const FX_RECT* pSrcRect, - int dest_left, int dest_top, int blend_type, - int alpha_flag = 0, void* pIccTransform = NULL); - virtual FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, int dest_left, int dest_top, - int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags, - int alpha_flag = 0, void* pIccTransform = NULL); - - virtual FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap, int bitmap_alpha, FX_DWORD color, - const CFX_AffineMatrix* pMatrix, FX_DWORD flags, void*& handle, - int alpha_flag = 0, void* pIccTransform = NULL); - virtual FX_BOOL ContinueDIBits(void* handle, IFX_Pause* pPause); - virtual void CancelDIBits(void* handle); - - virtual FX_BOOL DrawDeviceText(int nChars, const FXTEXT_CHARPOS* pCharPos, CFX_Font* pFont, - CFX_FontCache* pCache, const CFX_AffineMatrix* pObject2Device, FX_FIXFLOAT font_size, FX_DWORD color, - int alpha_flag = 0, void* pIccTransform = NULL); - - virtual FX_BOOL RenderRasterizer(rasterizer_scanline_aa& rasterizer, FX_DWORD color, FX_BOOL bFullCover, FX_BOOL bGroupKnockout, - int alpha_flag, void* pIccTransform); - virtual FX_BOOL RenderRasterizerSkia(SkPath& skPath, const SkPaint& origPaint, SkIRect& rect, FX_DWORD color, FX_BOOL bFullCover, FX_BOOL bGroupKnockout, - int alpha_flag, void* pIccTransform, FX_BOOL bFill = TRUE); - void SetClipMask(rasterizer_scanline_aa& rasterizer); - void SetClipMask(SkPath& skPath, SkPaint* spaint); - virtual uint8_t* GetBuffer() const {return m_pAggDriver->GetBuffer();} - - CFX_AggDeviceDriver* m_pAggDriver; +class CFX_SkiaDeviceDriver : public IFX_RenderDeviceDriver { + public: + CFX_SkiaDeviceDriver(CFX_DIBitmap* pBitmap, + int dither_bits, + FX_BOOL bRgbByteOrder, + CFX_DIBitmap* pOriDevice, + FX_BOOL bGroupKnockout); + virtual ~CFX_SkiaDeviceDriver(); + + /** Options */ + virtual int GetDeviceCaps(int caps_id); + + /** Save and restore all graphic states */ + virtual void SaveState(); + virtual void RestoreState(FX_BOOL bKeepSaved); + + /** Set clipping path using filled region */ + virtual FX_BOOL SetClip_PathFill( + const CFX_PathData* pPathData, // path info + const CFX_AffineMatrix* pObject2Device, // optional transformation + int fill_mode // fill mode, WINDING or ALTERNATE + ); + + /** Set clipping path using stroked region */ + virtual FX_BOOL SetClip_PathStroke( + const CFX_PathData* pPathData, // path info + const CFX_AffineMatrix* pObject2Device, // optional transformation + const CFX_GraphStateData* + pGraphState // graphic state, for pen attributes + ); + + /** Draw a path */ + virtual FX_BOOL DrawPath(const CFX_PathData* pPathData, + const CFX_AffineMatrix* pObject2Device, + const CFX_GraphStateData* pGraphState, + FX_DWORD fill_color, + FX_DWORD stroke_color, + int fill_mode, + int alpha_flag = 0, + void* pIccTransform = NULL); + + virtual FX_BOOL SetPixel(int x, + int y, + FX_DWORD color, + int alpha_flag = 0, + void* pIccTransform = NULL); + + virtual FX_BOOL FillRect(const FX_RECT* pRect, + FX_DWORD fill_color, + int alpha_flag = 0, + void* pIccTransform = NULL); + + /** Draw a single pixel (device dependant) line */ + virtual FX_BOOL DrawCosmeticLine(FX_FIXFLOAT x1, + FX_FIXFLOAT y1, + FX_FIXFLOAT x2, + FX_FIXFLOAT y2, + FX_DWORD color, + int alpha_flag, + void* pIccTransform, + int blend_type) { + return FALSE; + } + + virtual FX_BOOL GetClipBox(FX_RECT* pRect); + + /** Load device buffer into a DIB */ + virtual FX_BOOL GetDIBits(CFX_DIBitmap* pBitmap, + int left, + int top, + void* pIccTransform = NULL, + FX_BOOL bDEdge = FALSE); + + virtual CFX_DIBitmap* GetBackDrop() { return m_pAggDriver->GetBackDrop(); } + + virtual FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap, + FX_DWORD color, + const FX_RECT* pSrcRect, + int dest_left, + int dest_top, + int blend_type, + int alpha_flag = 0, + void* pIccTransform = NULL); + virtual FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap, + FX_DWORD color, + int dest_left, + int dest_top, + int dest_width, + int dest_height, + const FX_RECT* pClipRect, + FX_DWORD flags, + int alpha_flag = 0, + void* pIccTransform = NULL); + + virtual FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap, + int bitmap_alpha, + FX_DWORD color, + const CFX_AffineMatrix* pMatrix, + FX_DWORD flags, + void*& handle, + int alpha_flag = 0, + void* pIccTransform = NULL); + virtual FX_BOOL ContinueDIBits(void* handle, IFX_Pause* pPause); + virtual void CancelDIBits(void* handle); + + virtual FX_BOOL DrawDeviceText(int nChars, + const FXTEXT_CHARPOS* pCharPos, + CFX_Font* pFont, + CFX_FontCache* pCache, + const CFX_AffineMatrix* pObject2Device, + FX_FIXFLOAT font_size, + FX_DWORD color, + int alpha_flag = 0, + void* pIccTransform = NULL); + + virtual FX_BOOL RenderRasterizer(rasterizer_scanline_aa& rasterizer, + FX_DWORD color, + FX_BOOL bFullCover, + FX_BOOL bGroupKnockout, + int alpha_flag, + void* pIccTransform); + virtual FX_BOOL RenderRasterizerSkia(SkPath& skPath, + const SkPaint& origPaint, + SkIRect& rect, + FX_DWORD color, + FX_BOOL bFullCover, + FX_BOOL bGroupKnockout, + int alpha_flag, + void* pIccTransform, + FX_BOOL bFill = TRUE); + void SetClipMask(rasterizer_scanline_aa& rasterizer); + void SetClipMask(SkPath& skPath, SkPaint* spaint); + virtual uint8_t* GetBuffer() const { return m_pAggDriver->GetBuffer(); } + + CFX_AggDeviceDriver* m_pAggDriver; }; #endif // defined(_SKIA_SUPPORT_) diff --git a/core/src/fxge/win32/dwrite_int.h b/core/src/fxge/win32/dwrite_int.h index dc2a338935..a2c91ce5b4 100644 --- a/core/src/fxge/win32/dwrite_int.h +++ b/core/src/fxge/win32/dwrite_int.h @@ -8,54 +8,59 @@ #define CORE_SRC_FXGE_WIN32_DWRITE_INT_H_ #ifndef DECLSPEC_UUID -#if (_MSC_VER >= 1100) && defined (__cplusplus) -#define DECLSPEC_UUID(x) __declspec(uuid(x)) +#if (_MSC_VER >= 1100) && defined(__cplusplus) +#define DECLSPEC_UUID(x) __declspec(uuid(x)) #else #define DECLSPEC_UUID(x) #endif #endif #ifndef DECLSPEC_NOVTABLE #if (_MSC_VER >= 1100) && defined(__cplusplus) -#define DECLSPEC_NOVTABLE __declspec(novtable) +#define DECLSPEC_NOVTABLE __declspec(novtable) #else #define DECLSPEC_NOVTABLE #endif #endif -#if(WINVER < 0x0500) +#if (WINVER < 0x0500) #ifndef _MAC DECLARE_HANDLE(HMONITOR); #endif #endif -class CDWriteExt -{ -public: - CDWriteExt(); - ~CDWriteExt(); - - void Load(); - void Unload(); - - FX_BOOL IsAvailable() - { - return m_pDWriteFactory != NULL; - } - - void* DwCreateFontFaceFromStream(uint8_t* pData, FX_DWORD size, int simulation_style); - FX_BOOL DwCreateRenderingTarget(CFX_DIBitmap* pSrc, void** renderTarget); - void DwDeleteRenderingTarget(void* renderTarget); - FX_BOOL DwRendingString(void* renderTarget, CFX_ClipRgn* pClipRgn, FX_RECT& stringRect, CFX_AffineMatrix* pMatrix, - void *font, FX_FLOAT font_size, FX_ARGB text_color, - int glyph_count, unsigned short* glyph_indices, - FX_FLOAT baselineOriginX, FX_FLOAT baselineOriginY, - void* glyph_offsets, - FX_FLOAT* glyph_advances); - void DwDeleteFont(void* pFont); - -protected: - void* m_hModule; - void* m_pDWriteFactory; - void* m_pDwFontContext; - void* m_pDwTextRenderer; +class CDWriteExt { + public: + CDWriteExt(); + ~CDWriteExt(); + + void Load(); + void Unload(); + + FX_BOOL IsAvailable() { return m_pDWriteFactory != NULL; } + + void* DwCreateFontFaceFromStream(uint8_t* pData, + FX_DWORD size, + int simulation_style); + FX_BOOL DwCreateRenderingTarget(CFX_DIBitmap* pSrc, void** renderTarget); + void DwDeleteRenderingTarget(void* renderTarget); + FX_BOOL DwRendingString(void* renderTarget, + CFX_ClipRgn* pClipRgn, + FX_RECT& stringRect, + CFX_AffineMatrix* pMatrix, + void* font, + FX_FLOAT font_size, + FX_ARGB text_color, + int glyph_count, + unsigned short* glyph_indices, + FX_FLOAT baselineOriginX, + FX_FLOAT baselineOriginY, + void* glyph_offsets, + FX_FLOAT* glyph_advances); + void DwDeleteFont(void* pFont); + + protected: + void* m_hModule; + void* m_pDWriteFactory; + void* m_pDwFontContext; + void* m_pDwTextRenderer; }; #endif // CORE_SRC_FXGE_WIN32_DWRITE_INT_H_ diff --git a/core/src/fxge/win32/fx_win32_device.cpp b/core/src/fxge/win32/fx_win32_device.cpp index b068ffbaec..4cfc6cbf82 100644 --- a/core/src/fxge/win32/fx_win32_device.cpp +++ b/core/src/fxge/win32/fx_win32_device.cpp @@ -18,155 +18,153 @@ #include "dwrite_int.h" #include "win32_int.h" -class CFX_Win32FontInfo final : public IFX_SystemFontInfo -{ -public: - CFX_Win32FontInfo(); - ~CFX_Win32FontInfo(); - virtual void Release(); - virtual FX_BOOL EnumFontList(CFX_FontMapper* pMapper); - virtual void* MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, const FX_CHAR* face, int& iExact); - virtual void* GetFont(const FX_CHAR* face) - { - return NULL; - } - virtual FX_DWORD GetFontData(void* hFont, FX_DWORD table, uint8_t* buffer, FX_DWORD size); - virtual void DeleteFont(void* hFont); - virtual FX_BOOL GetFaceName(void* hFont, CFX_ByteString& name); - virtual FX_BOOL GetFontCharset(void* hFont, int& charset); - FX_BOOL IsOpenTypeFromDiv(const LOGFONTA *plf); - FX_BOOL IsSupportFontFormDiv(const LOGFONTA* plf); - void AddInstalledFont(const LOGFONTA *plf, FX_DWORD FontType); - void GetGBPreference(CFX_ByteString& face, int weight, int picth_family); - void GetJapanesePreference(CFX_ByteString& face, int weight, int picth_family); - CFX_ByteString FindFont(const CFX_ByteString& name); - HDC m_hDC; - CFX_FontMapper* m_pMapper; - CFX_ByteString m_LastFamily; - CFX_ByteString m_KaiTi, m_FangSong; +class CFX_Win32FontInfo final : public IFX_SystemFontInfo { + public: + CFX_Win32FontInfo(); + ~CFX_Win32FontInfo(); + virtual void Release(); + virtual FX_BOOL EnumFontList(CFX_FontMapper* pMapper); + virtual void* MapFont(int weight, + FX_BOOL bItalic, + int charset, + int pitch_family, + const FX_CHAR* face, + int& iExact); + virtual void* GetFont(const FX_CHAR* face) { return NULL; } + virtual FX_DWORD GetFontData(void* hFont, + FX_DWORD table, + uint8_t* buffer, + FX_DWORD size); + virtual void DeleteFont(void* hFont); + virtual FX_BOOL GetFaceName(void* hFont, CFX_ByteString& name); + virtual FX_BOOL GetFontCharset(void* hFont, int& charset); + FX_BOOL IsOpenTypeFromDiv(const LOGFONTA* plf); + FX_BOOL IsSupportFontFormDiv(const LOGFONTA* plf); + void AddInstalledFont(const LOGFONTA* plf, FX_DWORD FontType); + void GetGBPreference(CFX_ByteString& face, int weight, int picth_family); + void GetJapanesePreference(CFX_ByteString& face, + int weight, + int picth_family); + CFX_ByteString FindFont(const CFX_ByteString& name); + HDC m_hDC; + CFX_FontMapper* m_pMapper; + CFX_ByteString m_LastFamily; + CFX_ByteString m_KaiTi, m_FangSong; }; -CFX_Win32FontInfo::CFX_Win32FontInfo() -{ - m_hDC = CreateCompatibleDC(NULL); +CFX_Win32FontInfo::CFX_Win32FontInfo() { + m_hDC = CreateCompatibleDC(NULL); } -CFX_Win32FontInfo::~CFX_Win32FontInfo() -{ - m_pMapper = NULL; +CFX_Win32FontInfo::~CFX_Win32FontInfo() { + m_pMapper = NULL; } -void CFX_Win32FontInfo::Release() -{ - DeleteDC(m_hDC); - delete this; +void CFX_Win32FontInfo::Release() { + DeleteDC(m_hDC); + delete this; } -#define TT_MAKE_TAG(x1, x2, x3, x4) (((FX_DWORD)x1<<24)|((FX_DWORD)x2<<16)|((FX_DWORD)x3<<8)|(FX_DWORD)x4) -FX_BOOL CFX_Win32FontInfo::IsOpenTypeFromDiv(const LOGFONTA *plf) -{ - HFONT hFont = CreateFontIndirectA(plf); - FX_BOOL ret = FALSE; - FX_DWORD font_size = GetFontData(hFont, 0, NULL, 0); - if (font_size != GDI_ERROR && font_size >= sizeof(FX_DWORD)) { - FX_DWORD lVersion = 0; - GetFontData(hFont, 0, (uint8_t*)(&lVersion), sizeof(FX_DWORD)); - lVersion = (((FX_DWORD)(uint8_t)(lVersion)) << 24) | ((FX_DWORD)((uint8_t)(lVersion >> 8))) << 16 | - ((FX_DWORD)((uint8_t)(lVersion >> 16))) << 8 | ((uint8_t)(lVersion >> 24)); - if (lVersion == TT_MAKE_TAG('O', 'T', 'T', 'O') || - lVersion == 0x00010000 || - lVersion == TT_MAKE_TAG('t', 't', 'c', 'f') || - lVersion == TT_MAKE_TAG('t', 'r', 'u', 'e') || - lVersion == 0x00020000) { - ret = TRUE; - } - } - DeleteFont(hFont); - return ret; +#define TT_MAKE_TAG(x1, x2, x3, x4) \ + (((FX_DWORD)x1 << 24) | ((FX_DWORD)x2 << 16) | ((FX_DWORD)x3 << 8) | \ + (FX_DWORD)x4) +FX_BOOL CFX_Win32FontInfo::IsOpenTypeFromDiv(const LOGFONTA* plf) { + HFONT hFont = CreateFontIndirectA(plf); + FX_BOOL ret = FALSE; + FX_DWORD font_size = GetFontData(hFont, 0, NULL, 0); + if (font_size != GDI_ERROR && font_size >= sizeof(FX_DWORD)) { + FX_DWORD lVersion = 0; + GetFontData(hFont, 0, (uint8_t*)(&lVersion), sizeof(FX_DWORD)); + lVersion = (((FX_DWORD)(uint8_t)(lVersion)) << 24) | + ((FX_DWORD)((uint8_t)(lVersion >> 8))) << 16 | + ((FX_DWORD)((uint8_t)(lVersion >> 16))) << 8 | + ((uint8_t)(lVersion >> 24)); + if (lVersion == TT_MAKE_TAG('O', 'T', 'T', 'O') || lVersion == 0x00010000 || + lVersion == TT_MAKE_TAG('t', 't', 'c', 'f') || + lVersion == TT_MAKE_TAG('t', 'r', 'u', 'e') || lVersion == 0x00020000) { + ret = TRUE; + } + } + DeleteFont(hFont); + return ret; } -FX_BOOL CFX_Win32FontInfo::IsSupportFontFormDiv(const LOGFONTA* plf) -{ - HFONT hFont = CreateFontIndirectA(plf); - FX_BOOL ret = FALSE; - FX_DWORD font_size = GetFontData(hFont, 0, NULL, 0); - if (font_size != GDI_ERROR && font_size >= sizeof(FX_DWORD)) { - FX_DWORD lVersion = 0; - GetFontData(hFont, 0, (uint8_t*)(&lVersion), sizeof(FX_DWORD)); - lVersion = (((FX_DWORD)(uint8_t)(lVersion)) << 24) | ((FX_DWORD)((uint8_t)(lVersion >> 8))) << 16 | - ((FX_DWORD)((uint8_t)(lVersion >> 16))) << 8 | ((uint8_t)(lVersion >> 24)); - if (lVersion == TT_MAKE_TAG('O', 'T', 'T', 'O') || - lVersion == 0x00010000 || - lVersion == TT_MAKE_TAG('t', 't', 'c', 'f') || - lVersion == TT_MAKE_TAG('t', 'r', 'u', 'e') || - lVersion == 0x00020000) { - ret = TRUE; - } else if ((lVersion & 0xFFFF0000) == TT_MAKE_TAG(0x80, 0x01, 0x00, 0x00) || - (lVersion & 0xFFFF0000) == TT_MAKE_TAG('%', '!', 0, 0)) { - ret = TRUE; - } - } - DeleteFont(hFont); - return ret; +FX_BOOL CFX_Win32FontInfo::IsSupportFontFormDiv(const LOGFONTA* plf) { + HFONT hFont = CreateFontIndirectA(plf); + FX_BOOL ret = FALSE; + FX_DWORD font_size = GetFontData(hFont, 0, NULL, 0); + if (font_size != GDI_ERROR && font_size >= sizeof(FX_DWORD)) { + FX_DWORD lVersion = 0; + GetFontData(hFont, 0, (uint8_t*)(&lVersion), sizeof(FX_DWORD)); + lVersion = (((FX_DWORD)(uint8_t)(lVersion)) << 24) | + ((FX_DWORD)((uint8_t)(lVersion >> 8))) << 16 | + ((FX_DWORD)((uint8_t)(lVersion >> 16))) << 8 | + ((uint8_t)(lVersion >> 24)); + if (lVersion == TT_MAKE_TAG('O', 'T', 'T', 'O') || lVersion == 0x00010000 || + lVersion == TT_MAKE_TAG('t', 't', 'c', 'f') || + lVersion == TT_MAKE_TAG('t', 'r', 'u', 'e') || lVersion == 0x00020000) { + ret = TRUE; + } else if ((lVersion & 0xFFFF0000) == TT_MAKE_TAG(0x80, 0x01, 0x00, 0x00) || + (lVersion & 0xFFFF0000) == TT_MAKE_TAG('%', '!', 0, 0)) { + ret = TRUE; + } + } + DeleteFont(hFont); + return ret; } -void CFX_Win32FontInfo::AddInstalledFont(const LOGFONTA *plf, FX_DWORD FontType) -{ - CFX_ByteString name(plf->lfFaceName, -1); - if (name[0] == '@') { - return; - } - if (name == m_LastFamily) { - m_pMapper->AddInstalledFont(name, plf->lfCharSet); - return; - } - if (!(FontType & TRUETYPE_FONTTYPE) && !(FontType & DEVICE_FONTTYPE)) { - return; - } - if (!(FontType & TRUETYPE_FONTTYPE)) { - if (!IsSupportFontFormDiv(plf)) { - return; - } - } +void CFX_Win32FontInfo::AddInstalledFont(const LOGFONTA* plf, + FX_DWORD FontType) { + CFX_ByteString name(plf->lfFaceName, -1); + if (name[0] == '@') { + return; + } + if (name == m_LastFamily) { m_pMapper->AddInstalledFont(name, plf->lfCharSet); - m_LastFamily = name; + return; + } + if (!(FontType & TRUETYPE_FONTTYPE) && !(FontType & DEVICE_FONTTYPE)) { + return; + } + if (!(FontType & TRUETYPE_FONTTYPE)) { + if (!IsSupportFontFormDiv(plf)) { + return; + } + } + m_pMapper->AddInstalledFont(name, plf->lfCharSet); + m_LastFamily = name; } -static int CALLBACK FontEnumProc( - const LOGFONTA *plf, - const TEXTMETRICA *lpntme, - FX_DWORD FontType, - LPARAM lParam -) -{ - CFX_Win32FontInfo* pFontInfo = (CFX_Win32FontInfo*)lParam; - if (pFontInfo->m_pMapper->GetFontEnumerator()) { - pFontInfo->m_pMapper->GetFontEnumerator()->HitFont(); - } - pFontInfo->AddInstalledFont(plf, FontType); - return 1; +static int CALLBACK FontEnumProc(const LOGFONTA* plf, + const TEXTMETRICA* lpntme, + FX_DWORD FontType, + LPARAM lParam) { + CFX_Win32FontInfo* pFontInfo = (CFX_Win32FontInfo*)lParam; + if (pFontInfo->m_pMapper->GetFontEnumerator()) { + pFontInfo->m_pMapper->GetFontEnumerator()->HitFont(); + } + pFontInfo->AddInstalledFont(plf, FontType); + return 1; } -FX_BOOL CFX_Win32FontInfo::EnumFontList(CFX_FontMapper* pMapper) -{ - m_pMapper = pMapper; - LOGFONTA lf; - FXSYS_memset(&lf, 0, sizeof(LOGFONTA)); - lf.lfCharSet = DEFAULT_CHARSET; - lf.lfFaceName[0] = 0; - lf.lfPitchAndFamily = 0; - EnumFontFamiliesExA(m_hDC, &lf, (FONTENUMPROCA)FontEnumProc, (uintptr_t)this, 0); - if (pMapper->GetFontEnumerator()) { - pMapper->GetFontEnumerator()->Finish(); - } - return TRUE; +FX_BOOL CFX_Win32FontInfo::EnumFontList(CFX_FontMapper* pMapper) { + m_pMapper = pMapper; + LOGFONTA lf; + FXSYS_memset(&lf, 0, sizeof(LOGFONTA)); + lf.lfCharSet = DEFAULT_CHARSET; + lf.lfFaceName[0] = 0; + lf.lfPitchAndFamily = 0; + EnumFontFamiliesExA(m_hDC, &lf, (FONTENUMPROCA)FontEnumProc, (uintptr_t) this, + 0); + if (pMapper->GetFontEnumerator()) { + pMapper->GetFontEnumerator()->Finish(); + } + return TRUE; } static const struct { - const FX_CHAR* m_pFaceName; - const FX_CHAR* m_pVariantName; -} -VariantNames[] = { + const FX_CHAR* m_pFaceName; + const FX_CHAR* m_pVariantName; +} VariantNames[] = { {"DFKai-SB", "\x19\x6A\x77\x69\xD4\x9A"}, }; static const struct { - const FX_CHAR* m_pName; - const FX_CHAR* m_pWinName; - FX_BOOL m_bBold; - FX_BOOL m_bItalic; -} -Base14Substs[] = { + const FX_CHAR* m_pName; + const FX_CHAR* m_pWinName; + FX_BOOL m_bBold; + FX_BOOL m_bItalic; +} Base14Substs[] = { {"Courier", "Courier New", FALSE, FALSE}, {"Courier-Bold", "Courier New", TRUE, FALSE}, {"Courier-BoldOblique", "Courier New", TRUE, TRUE}, @@ -180,578 +178,617 @@ Base14Substs[] = { {"Times-BoldItalic", "Times New Roman", TRUE, TRUE}, {"Times-Italic", "Times New Roman", FALSE, TRUE}, }; -CFX_ByteString CFX_Win32FontInfo::FindFont(const CFX_ByteString& name) -{ - if (m_pMapper == NULL) { - return name; - } - int nFonts = m_pMapper->m_InstalledTTFonts.GetSize(); - for (int i = 0; i < nFonts; i ++) { - CFX_ByteString thisname = m_pMapper->m_InstalledTTFonts[i]; - if (thisname[0] == ' ') { - if (thisname.Mid(1, name.GetLength()) == name) { - return m_pMapper->m_InstalledTTFonts[i + 1]; - } - } else if (thisname.Left(name.GetLength()) == name) { - return m_pMapper->m_InstalledTTFonts[i]; - } - } - return CFX_ByteString(); +CFX_ByteString CFX_Win32FontInfo::FindFont(const CFX_ByteString& name) { + if (m_pMapper == NULL) { + return name; + } + int nFonts = m_pMapper->m_InstalledTTFonts.GetSize(); + for (int i = 0; i < nFonts; i++) { + CFX_ByteString thisname = m_pMapper->m_InstalledTTFonts[i]; + if (thisname[0] == ' ') { + if (thisname.Mid(1, name.GetLength()) == name) { + return m_pMapper->m_InstalledTTFonts[i + 1]; + } + } else if (thisname.Left(name.GetLength()) == name) { + return m_pMapper->m_InstalledTTFonts[i]; + } + } + return CFX_ByteString(); } struct _FontNameMap { - const FX_CHAR* m_pSubFontName; - const FX_CHAR* m_pSrcFontName; + const FX_CHAR* m_pSubFontName; + const FX_CHAR* m_pSrcFontName; }; const _FontNameMap g_JpFontNameMap[] = { {"MS Mincho", "Heiseimin-W3"}, {"MS Gothic", "Jun101-Light"}, }; extern "C" { - static int compareString(const void* key, const void* element) - { - return FXSYS_stricmp((const FX_CHAR*)key, ((_FontNameMap*)element)->m_pSrcFontName); - } +static int compareString(const void* key, const void* element) { + return FXSYS_stricmp((const FX_CHAR*)key, + ((_FontNameMap*)element)->m_pSrcFontName); } -FX_BOOL _GetSubFontName(CFX_ByteString& name) -{ - int size = sizeof g_JpFontNameMap; - void* pFontnameMap = (void*)g_JpFontNameMap; - _FontNameMap* found = (_FontNameMap*)FXSYS_bsearch(name.c_str(), pFontnameMap, - size / sizeof (_FontNameMap), sizeof (_FontNameMap), compareString); - if (found == NULL) { - return FALSE; - } - name = found->m_pSubFontName; - return TRUE; } -void CFX_Win32FontInfo::GetGBPreference(CFX_ByteString& face, int weight, int picth_family) -{ - if (face.Find("KaiTi") >= 0 || face.Find("\xbf\xac") >= 0) { - if (m_KaiTi.IsEmpty()) { - m_KaiTi = FindFont("KaiTi"); - if (m_KaiTi.IsEmpty()) { - m_KaiTi = "SimSun"; - } - } - face = m_KaiTi; - } else if (face.Find("FangSong") >= 0 || face.Find("\xb7\xc2\xcb\xce") >= 0) { - if (m_FangSong.IsEmpty()) { - m_FangSong = FindFont("FangSong"); - if (m_FangSong.IsEmpty()) { - m_FangSong = "SimSun"; - } - } - face = m_FangSong; - } else if (face.Find("SimSun") >= 0 || face.Find("\xcb\xce") >= 0) { - face = "SimSun"; - } else if (face.Find("SimHei") >= 0 || face.Find("\xba\xda") >= 0) { - face = "SimHei"; - } else if (!(picth_family & FF_ROMAN) && weight > 550) { - face = "SimHei"; - } else { - face = "SimSun"; - } +FX_BOOL _GetSubFontName(CFX_ByteString& name) { + int size = sizeof g_JpFontNameMap; + void* pFontnameMap = (void*)g_JpFontNameMap; + _FontNameMap* found = (_FontNameMap*)FXSYS_bsearch( + name.c_str(), pFontnameMap, size / sizeof(_FontNameMap), + sizeof(_FontNameMap), compareString); + if (found == NULL) { + return FALSE; + } + name = found->m_pSubFontName; + return TRUE; } -void CFX_Win32FontInfo::GetJapanesePreference(CFX_ByteString& face, int weight, int picth_family) -{ - if (face.Find("Gothic") >= 0 || face.Find("\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) { - if (face.Find("PGothic") >= 0 || face.Find("\x82\x6f\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) { - face = "MS PGothic"; - } else if (face.Find("UI Gothic") >= 0) { - face = "MS UI Gothic"; - } else { - if (face.Find("HGSGothicM") >= 0 || face.Find("HGMaruGothicMPRO") >= 0) { - face = "MS PGothic"; - } else { - face = "MS Gothic"; - } - } - return; - } - if (face.Find("Mincho") >= 0 || face.Find("\x96\xbe\x92\xa9") >= 0) { - if (face.Find("PMincho") >= 0 || face.Find("\x82\x6f\x96\xbe\x92\xa9") >= 0) { - face = "MS PMincho"; - } else { - face = "MS Mincho"; - } - return; - } - if (_GetSubFontName(face)) { - return; - } - if (!(picth_family & FF_ROMAN) && weight > 400) { +void CFX_Win32FontInfo::GetGBPreference(CFX_ByteString& face, + int weight, + int picth_family) { + if (face.Find("KaiTi") >= 0 || face.Find("\xbf\xac") >= 0) { + if (m_KaiTi.IsEmpty()) { + m_KaiTi = FindFont("KaiTi"); + if (m_KaiTi.IsEmpty()) { + m_KaiTi = "SimSun"; + } + } + face = m_KaiTi; + } else if (face.Find("FangSong") >= 0 || face.Find("\xb7\xc2\xcb\xce") >= 0) { + if (m_FangSong.IsEmpty()) { + m_FangSong = FindFont("FangSong"); + if (m_FangSong.IsEmpty()) { + m_FangSong = "SimSun"; + } + } + face = m_FangSong; + } else if (face.Find("SimSun") >= 0 || face.Find("\xcb\xce") >= 0) { + face = "SimSun"; + } else if (face.Find("SimHei") >= 0 || face.Find("\xba\xda") >= 0) { + face = "SimHei"; + } else if (!(picth_family & FF_ROMAN) && weight > 550) { + face = "SimHei"; + } else { + face = "SimSun"; + } +} +void CFX_Win32FontInfo::GetJapanesePreference(CFX_ByteString& face, + int weight, + int picth_family) { + if (face.Find("Gothic") >= 0 || + face.Find("\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) { + if (face.Find("PGothic") >= 0 || + face.Find("\x82\x6f\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) { + face = "MS PGothic"; + } else if (face.Find("UI Gothic") >= 0) { + face = "MS UI Gothic"; + } else { + if (face.Find("HGSGothicM") >= 0 || face.Find("HGMaruGothicMPRO") >= 0) { face = "MS PGothic"; + } else { + face = "MS Gothic"; + } + } + return; + } + if (face.Find("Mincho") >= 0 || face.Find("\x96\xbe\x92\xa9") >= 0) { + if (face.Find("PMincho") >= 0 || + face.Find("\x82\x6f\x96\xbe\x92\xa9") >= 0) { + face = "MS PMincho"; } else { - face = "MS PMincho"; - } + face = "MS Mincho"; + } + return; + } + if (_GetSubFontName(face)) { + return; + } + if (!(picth_family & FF_ROMAN) && weight > 400) { + face = "MS PGothic"; + } else { + face = "MS PMincho"; + } } -void* CFX_Win32FontInfo::MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, const FX_CHAR* cstr_face, int& iExact) -{ - CFX_ByteString face = cstr_face; - int iBaseFont; - for (iBaseFont = 0; iBaseFont < 12; iBaseFont ++) - if (face == CFX_ByteStringC(Base14Substs[iBaseFont].m_pName)) { - face = Base14Substs[iBaseFont].m_pWinName; - weight = Base14Substs[iBaseFont].m_bBold ? FW_BOLD : FW_NORMAL; - bItalic = Base14Substs[iBaseFont].m_bItalic; - iExact = TRUE; - break; - } - if (charset == ANSI_CHARSET || charset == SYMBOL_CHARSET) { - charset = DEFAULT_CHARSET; - } - int subst_pitch_family = pitch_family; - switch (charset) { - case SHIFTJIS_CHARSET: - subst_pitch_family = FF_ROMAN; - break; - case CHINESEBIG5_CHARSET: - case HANGUL_CHARSET: - case GB2312_CHARSET: - subst_pitch_family = 0; - break; - } - HFONT hFont = ::CreateFontA(-10, 0, 0, 0, weight, bItalic, 0, 0, charset, OUT_TT_ONLY_PRECIS, - 0, 0, subst_pitch_family, face); - char facebuf[100]; - HFONT hOldFont = (HFONT)::SelectObject(m_hDC, hFont); - int ret = ::GetTextFaceA(m_hDC, 100, facebuf); - ::SelectObject(m_hDC, hOldFont); - if (face.EqualNoCase(facebuf)) { - return hFont; - } - int iCount = sizeof(VariantNames) / sizeof(VariantNames[0]); - for (int i = 0; i < iCount; ++i) { - if (face == VariantNames[i].m_pFaceName) { - CFX_WideString wsFace = CFX_WideString::FromLocal(facebuf); - const unsigned short* pName = (const unsigned short*)VariantNames[i].m_pVariantName; - FX_STRSIZE len = CFX_WideString::WStringLength(pName); - CFX_WideString wsName = CFX_WideString::FromUTF16LE(pName, len); - if (wsFace == wsName) { - return hFont; - } - } - } - ::DeleteObject(hFont); - if (charset == DEFAULT_CHARSET) { - return NULL; - } - switch (charset) { - case SHIFTJIS_CHARSET: - GetJapanesePreference(face, weight, pitch_family); - break; - case GB2312_CHARSET: - GetGBPreference(face, weight, pitch_family); - break; - case HANGUL_CHARSET: - face = "Gulim"; - break; - case CHINESEBIG5_CHARSET: - if (face.Find("MSung") >= 0) { - face = "MingLiU"; - } else { - face = "PMingLiU"; - } - break; - } - hFont = ::CreateFontA(-10, 0, 0, 0, weight, bItalic, 0, 0, charset, OUT_TT_ONLY_PRECIS, - 0, 0, subst_pitch_family, face); +void* CFX_Win32FontInfo::MapFont(int weight, + FX_BOOL bItalic, + int charset, + int pitch_family, + const FX_CHAR* cstr_face, + int& iExact) { + CFX_ByteString face = cstr_face; + int iBaseFont; + for (iBaseFont = 0; iBaseFont < 12; iBaseFont++) + if (face == CFX_ByteStringC(Base14Substs[iBaseFont].m_pName)) { + face = Base14Substs[iBaseFont].m_pWinName; + weight = Base14Substs[iBaseFont].m_bBold ? FW_BOLD : FW_NORMAL; + bItalic = Base14Substs[iBaseFont].m_bItalic; + iExact = TRUE; + break; + } + if (charset == ANSI_CHARSET || charset == SYMBOL_CHARSET) { + charset = DEFAULT_CHARSET; + } + int subst_pitch_family = pitch_family; + switch (charset) { + case SHIFTJIS_CHARSET: + subst_pitch_family = FF_ROMAN; + break; + case CHINESEBIG5_CHARSET: + case HANGUL_CHARSET: + case GB2312_CHARSET: + subst_pitch_family = 0; + break; + } + HFONT hFont = + ::CreateFontA(-10, 0, 0, 0, weight, bItalic, 0, 0, charset, + OUT_TT_ONLY_PRECIS, 0, 0, subst_pitch_family, face); + char facebuf[100]; + HFONT hOldFont = (HFONT)::SelectObject(m_hDC, hFont); + int ret = ::GetTextFaceA(m_hDC, 100, facebuf); + ::SelectObject(m_hDC, hOldFont); + if (face.EqualNoCase(facebuf)) { return hFont; + } + int iCount = sizeof(VariantNames) / sizeof(VariantNames[0]); + for (int i = 0; i < iCount; ++i) { + if (face == VariantNames[i].m_pFaceName) { + CFX_WideString wsFace = CFX_WideString::FromLocal(facebuf); + const unsigned short* pName = + (const unsigned short*)VariantNames[i].m_pVariantName; + FX_STRSIZE len = CFX_WideString::WStringLength(pName); + CFX_WideString wsName = CFX_WideString::FromUTF16LE(pName, len); + if (wsFace == wsName) { + return hFont; + } + } + } + ::DeleteObject(hFont); + if (charset == DEFAULT_CHARSET) { + return NULL; + } + switch (charset) { + case SHIFTJIS_CHARSET: + GetJapanesePreference(face, weight, pitch_family); + break; + case GB2312_CHARSET: + GetGBPreference(face, weight, pitch_family); + break; + case HANGUL_CHARSET: + face = "Gulim"; + break; + case CHINESEBIG5_CHARSET: + if (face.Find("MSung") >= 0) { + face = "MingLiU"; + } else { + face = "PMingLiU"; + } + break; + } + hFont = ::CreateFontA(-10, 0, 0, 0, weight, bItalic, 0, 0, charset, + OUT_TT_ONLY_PRECIS, 0, 0, subst_pitch_family, face); + return hFont; } -void CFX_Win32FontInfo::DeleteFont(void* hFont) -{ - ::DeleteObject(hFont); -} -FX_DWORD CFX_Win32FontInfo::GetFontData(void* hFont, FX_DWORD table, uint8_t* buffer, FX_DWORD size) -{ - HFONT hOldFont = (HFONT)::SelectObject(m_hDC, (HFONT)hFont); - table = FXDWORD_FROM_MSBFIRST(table); - size = ::GetFontData(m_hDC, table, 0, buffer, size); - ::SelectObject(m_hDC, hOldFont); - if (size == GDI_ERROR) { - return 0; - } - return size; +void CFX_Win32FontInfo::DeleteFont(void* hFont) { + ::DeleteObject(hFont); } -FX_BOOL CFX_Win32FontInfo::GetFaceName(void* hFont, CFX_ByteString& name) -{ - char facebuf[100]; - HFONT hOldFont = (HFONT)::SelectObject(m_hDC, (HFONT)hFont); - int ret = ::GetTextFaceA(m_hDC, 100, facebuf); - ::SelectObject(m_hDC, hOldFont); - if (ret == 0) { - return FALSE; - } - name = facebuf; - return TRUE; +FX_DWORD CFX_Win32FontInfo::GetFontData(void* hFont, + FX_DWORD table, + uint8_t* buffer, + FX_DWORD size) { + HFONT hOldFont = (HFONT)::SelectObject(m_hDC, (HFONT)hFont); + table = FXDWORD_FROM_MSBFIRST(table); + size = ::GetFontData(m_hDC, table, 0, buffer, size); + ::SelectObject(m_hDC, hOldFont); + if (size == GDI_ERROR) { + return 0; + } + return size; } -FX_BOOL CFX_Win32FontInfo::GetFontCharset(void* hFont, int& charset) -{ - TEXTMETRIC tm; - HFONT hOldFont = (HFONT)::SelectObject(m_hDC, (HFONT)hFont); - ::GetTextMetrics(m_hDC, &tm); - ::SelectObject(m_hDC, hOldFont); - charset = tm.tmCharSet; - return TRUE; +FX_BOOL CFX_Win32FontInfo::GetFaceName(void* hFont, CFX_ByteString& name) { + char facebuf[100]; + HFONT hOldFont = (HFONT)::SelectObject(m_hDC, (HFONT)hFont); + int ret = ::GetTextFaceA(m_hDC, 100, facebuf); + ::SelectObject(m_hDC, hOldFont); + if (ret == 0) { + return FALSE; + } + name = facebuf; + return TRUE; } -IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault() -{ - return new CFX_Win32FontInfo; +FX_BOOL CFX_Win32FontInfo::GetFontCharset(void* hFont, int& charset) { + TEXTMETRIC tm; + HFONT hOldFont = (HFONT)::SelectObject(m_hDC, (HFONT)hFont); + ::GetTextMetrics(m_hDC, &tm); + ::SelectObject(m_hDC, hOldFont); + charset = tm.tmCharSet; + return TRUE; } -void CFX_GEModule::InitPlatform() -{ - CWin32Platform* pPlatformData = new CWin32Platform; - OSVERSIONINFO ver; - ver.dwOSVersionInfoSize = sizeof(ver); - GetVersionEx(&ver); - pPlatformData->m_bHalfTone = ver.dwMajorVersion >= 5; - pPlatformData->m_GdiplusExt.Load(); - m_pPlatformData = pPlatformData; - m_pFontMgr->SetSystemFontInfo(IFX_SystemFontInfo::CreateDefault()); +IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault() { + return new CFX_Win32FontInfo; } -void CFX_GEModule::DestroyPlatform() -{ - delete (CWin32Platform*)m_pPlatformData; - m_pPlatformData = NULL; +void CFX_GEModule::InitPlatform() { + CWin32Platform* pPlatformData = new CWin32Platform; + OSVERSIONINFO ver; + ver.dwOSVersionInfoSize = sizeof(ver); + GetVersionEx(&ver); + pPlatformData->m_bHalfTone = ver.dwMajorVersion >= 5; + pPlatformData->m_GdiplusExt.Load(); + m_pPlatformData = pPlatformData; + m_pFontMgr->SetSystemFontInfo(IFX_SystemFontInfo::CreateDefault()); } -CGdiDeviceDriver::CGdiDeviceDriver(HDC hDC, int device_class) -{ - m_hDC = hDC; - m_DeviceClass = device_class; - CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData(); - SetStretchBltMode(hDC, pPlatform->m_bHalfTone ? HALFTONE : COLORONCOLOR); - if (GetObjectType(m_hDC) == OBJ_MEMDC) { - HBITMAP hBitmap = CreateBitmap(1, 1, 1, 1, NULL); - hBitmap = (HBITMAP)SelectObject(m_hDC, hBitmap); - BITMAP bitmap; - GetObject(hBitmap, sizeof bitmap, &bitmap); - m_nBitsPerPixel = bitmap.bmBitsPixel; - m_Width = bitmap.bmWidth; - m_Height = abs(bitmap.bmHeight); - hBitmap = (HBITMAP)SelectObject(m_hDC, hBitmap); - DeleteObject(hBitmap); - } else { - m_nBitsPerPixel = ::GetDeviceCaps(m_hDC, BITSPIXEL); - m_Width = ::GetDeviceCaps(m_hDC, HORZRES); - m_Height = ::GetDeviceCaps(m_hDC, VERTRES); - } - if (m_DeviceClass != FXDC_DISPLAY) { - m_RenderCaps = FXRC_BIT_MASK; - } else { - m_RenderCaps = FXRC_GET_BITS | FXRC_BIT_MASK; - } +void CFX_GEModule::DestroyPlatform() { + delete (CWin32Platform*)m_pPlatformData; + m_pPlatformData = NULL; } -int CGdiDeviceDriver::GetDeviceCaps(int caps_id) -{ - switch (caps_id) { - case FXDC_DEVICE_CLASS: - return m_DeviceClass; - case FXDC_PIXEL_WIDTH: - return m_Width; - case FXDC_PIXEL_HEIGHT: - return m_Height; - case FXDC_BITS_PIXEL: - return m_nBitsPerPixel; - case FXDC_RENDER_CAPS: - return m_RenderCaps; - } - return 0; +CGdiDeviceDriver::CGdiDeviceDriver(HDC hDC, int device_class) { + m_hDC = hDC; + m_DeviceClass = device_class; + CWin32Platform* pPlatform = + (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData(); + SetStretchBltMode(hDC, pPlatform->m_bHalfTone ? HALFTONE : COLORONCOLOR); + if (GetObjectType(m_hDC) == OBJ_MEMDC) { + HBITMAP hBitmap = CreateBitmap(1, 1, 1, 1, NULL); + hBitmap = (HBITMAP)SelectObject(m_hDC, hBitmap); + BITMAP bitmap; + GetObject(hBitmap, sizeof bitmap, &bitmap); + m_nBitsPerPixel = bitmap.bmBitsPixel; + m_Width = bitmap.bmWidth; + m_Height = abs(bitmap.bmHeight); + hBitmap = (HBITMAP)SelectObject(m_hDC, hBitmap); + DeleteObject(hBitmap); + } else { + m_nBitsPerPixel = ::GetDeviceCaps(m_hDC, BITSPIXEL); + m_Width = ::GetDeviceCaps(m_hDC, HORZRES); + m_Height = ::GetDeviceCaps(m_hDC, VERTRES); + } + if (m_DeviceClass != FXDC_DISPLAY) { + m_RenderCaps = FXRC_BIT_MASK; + } else { + m_RenderCaps = FXRC_GET_BITS | FXRC_BIT_MASK; + } } -void* CGdiDeviceDriver::GetClipRgn() -{ - HRGN hClipRgn = CreateRectRgn(0, 0, 1, 1); - if (::GetClipRgn(m_hDC, hClipRgn) == 0) { - DeleteObject(hClipRgn); - hClipRgn = NULL; - } - return (void*)hClipRgn; +int CGdiDeviceDriver::GetDeviceCaps(int caps_id) { + switch (caps_id) { + case FXDC_DEVICE_CLASS: + return m_DeviceClass; + case FXDC_PIXEL_WIDTH: + return m_Width; + case FXDC_PIXEL_HEIGHT: + return m_Height; + case FXDC_BITS_PIXEL: + return m_nBitsPerPixel; + case FXDC_RENDER_CAPS: + return m_RenderCaps; + } + return 0; } -FX_BOOL CGdiDeviceDriver::GDI_SetDIBits(const CFX_DIBitmap* pBitmap1, const FX_RECT* pSrcRect, int left, int top, void* pIccTransform) -{ - if (m_DeviceClass == FXDC_PRINTER) { - CFX_DIBitmap* pBitmap = pBitmap1->FlipImage(FALSE, TRUE); - if (pBitmap == NULL) { - return FALSE; - } - if ((pBitmap->IsCmykImage() || pIccTransform) && - !pBitmap->ConvertFormat(FXDIB_Rgb, pIccTransform)) { - return FALSE; - } - int width = pSrcRect->Width(), height = pSrcRect->Height(); - int pitch = pBitmap->GetPitch(); - LPBYTE pBuffer = pBitmap->GetBuffer(); - CFX_ByteString info = CFX_WindowsDIB::GetBitmapInfo(pBitmap); - ((BITMAPINFOHEADER*)info.c_str())->biHeight *= -1; - FX_RECT dst_rect(0, 0, width, height); - dst_rect.Intersect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight()); - int dst_width = dst_rect.Width(); - int dst_height = dst_rect.Height(); - ::StretchDIBits(m_hDC, left, top, dst_width, dst_height, - 0, 0, dst_width, dst_height, pBuffer, (BITMAPINFO*)info.c_str(), DIB_RGB_COLORS, SRCCOPY); - delete pBitmap; - } else { - CFX_DIBitmap* pBitmap = (CFX_DIBitmap*)pBitmap1; - if ((pBitmap->IsCmykImage() || pIccTransform) && - (pBitmap = pBitmap->CloneConvert(FXDIB_Rgb, NULL, pIccTransform)) == NULL) { - return FALSE; - } - int width = pSrcRect->Width(), height = pSrcRect->Height(); - int pitch = pBitmap->GetPitch(); - LPBYTE pBuffer = pBitmap->GetBuffer(); - CFX_ByteString info = CFX_WindowsDIB::GetBitmapInfo(pBitmap); - ::SetDIBitsToDevice(m_hDC, left, top, width, height, pSrcRect->left, pBitmap->GetHeight() - pSrcRect->bottom, - 0, pBitmap->GetHeight(), pBuffer, (BITMAPINFO*)info.c_str(), DIB_RGB_COLORS); - if (pBitmap != pBitmap1) { - delete pBitmap; - } - } - return TRUE; +void* CGdiDeviceDriver::GetClipRgn() { + HRGN hClipRgn = CreateRectRgn(0, 0, 1, 1); + if (::GetClipRgn(m_hDC, hClipRgn) == 0) { + DeleteObject(hClipRgn); + hClipRgn = NULL; + } + return (void*)hClipRgn; } -FX_BOOL CGdiDeviceDriver::GDI_StretchDIBits(const CFX_DIBitmap* pBitmap1, int dest_left, int dest_top, - int dest_width, int dest_height, FX_DWORD flags, void* pIccTransform) -{ - CFX_DIBitmap* pBitmap = (CFX_DIBitmap*)pBitmap1; - if (pBitmap == NULL || dest_width == 0 || dest_height == 0) { - return FALSE; +FX_BOOL CGdiDeviceDriver::GDI_SetDIBits(const CFX_DIBitmap* pBitmap1, + const FX_RECT* pSrcRect, + int left, + int top, + void* pIccTransform) { + if (m_DeviceClass == FXDC_PRINTER) { + CFX_DIBitmap* pBitmap = pBitmap1->FlipImage(FALSE, TRUE); + if (pBitmap == NULL) { + return FALSE; } if ((pBitmap->IsCmykImage() || pIccTransform) && - !pBitmap->ConvertFormat(FXDIB_Rgb, pIccTransform)) { - return FALSE; + !pBitmap->ConvertFormat(FXDIB_Rgb, pIccTransform)) { + return FALSE; } + int width = pSrcRect->Width(), height = pSrcRect->Height(); + int pitch = pBitmap->GetPitch(); + LPBYTE pBuffer = pBitmap->GetBuffer(); CFX_ByteString info = CFX_WindowsDIB::GetBitmapInfo(pBitmap); - if ((int64_t)abs(dest_width) * abs(dest_height) < (int64_t)pBitmap1->GetWidth() * pBitmap1->GetHeight() * 4 || - (flags & FXDIB_INTERPOL) || (flags & FXDIB_BICUBIC_INTERPOL)) { - SetStretchBltMode(m_hDC, HALFTONE); - } else { - SetStretchBltMode(m_hDC, COLORONCOLOR); - } - CFX_DIBitmap* pToStrechBitmap = pBitmap; - bool del = false; - if (m_DeviceClass == FXDC_PRINTER && ((int64_t)pBitmap->GetWidth() * pBitmap->GetHeight() > (int64_t)abs(dest_width) * abs(dest_height))) { - pToStrechBitmap = pBitmap->StretchTo(dest_width, dest_height); - del = true; - } - CFX_ByteString toStrechBitmapInfo = CFX_WindowsDIB::GetBitmapInfo(pToStrechBitmap); - ::StretchDIBits(m_hDC, dest_left, dest_top, dest_width, dest_height, - 0, 0, pToStrechBitmap->GetWidth(), pToStrechBitmap->GetHeight(), pToStrechBitmap->GetBuffer(), - (BITMAPINFO*)toStrechBitmapInfo.c_str(), DIB_RGB_COLORS, SRCCOPY); - if (del) { - delete pToStrechBitmap; - } - return TRUE; -} -FX_BOOL CGdiDeviceDriver::GDI_StretchBitMask(const CFX_DIBitmap* pBitmap1, int dest_left, int dest_top, - int dest_width, int dest_height, FX_DWORD bitmap_color, FX_DWORD flags, - int alpha_flag, void* pIccTransform) -{ + ((BITMAPINFOHEADER*)info.c_str())->biHeight *= -1; + FX_RECT dst_rect(0, 0, width, height); + dst_rect.Intersect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight()); + int dst_width = dst_rect.Width(); + int dst_height = dst_rect.Height(); + ::StretchDIBits(m_hDC, left, top, dst_width, dst_height, 0, 0, dst_width, + dst_height, pBuffer, (BITMAPINFO*)info.c_str(), + DIB_RGB_COLORS, SRCCOPY); + delete pBitmap; + } else { CFX_DIBitmap* pBitmap = (CFX_DIBitmap*)pBitmap1; - if (pBitmap == NULL || dest_width == 0 || dest_height == 0) { - return FALSE; - } - _Color2Argb(bitmap_color, bitmap_color, alpha_flag | (1 << 24), pIccTransform); - int width = pBitmap->GetWidth(), height = pBitmap->GetHeight(); - struct { - BITMAPINFOHEADER bmiHeader; - FX_DWORD bmiColors[2]; - } bmi; - FXSYS_memset(&bmi.bmiHeader, 0, sizeof (BITMAPINFOHEADER)); - bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmi.bmiHeader.biBitCount = 1; - bmi.bmiHeader.biCompression = BI_RGB; - bmi.bmiHeader.biHeight = -height; - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biWidth = width; - if (m_nBitsPerPixel != 1) { - SetStretchBltMode(m_hDC, HALFTONE); + if ((pBitmap->IsCmykImage() || pIccTransform) && + (pBitmap = pBitmap->CloneConvert(FXDIB_Rgb, NULL, pIccTransform)) == + NULL) { + return FALSE; } - bmi.bmiColors[0] = 0xffffff; - bmi.bmiColors[1] = 0; - - HBRUSH hPattern = CreateSolidBrush(bitmap_color & 0xffffff); - HBRUSH hOld = (HBRUSH)SelectObject(m_hDC, hPattern); + int width = pSrcRect->Width(), height = pSrcRect->Height(); + int pitch = pBitmap->GetPitch(); + LPBYTE pBuffer = pBitmap->GetBuffer(); + CFX_ByteString info = CFX_WindowsDIB::GetBitmapInfo(pBitmap); + ::SetDIBitsToDevice(m_hDC, left, top, width, height, pSrcRect->left, + pBitmap->GetHeight() - pSrcRect->bottom, 0, + pBitmap->GetHeight(), pBuffer, + (BITMAPINFO*)info.c_str(), DIB_RGB_COLORS); + if (pBitmap != pBitmap1) { + delete pBitmap; + } + } + return TRUE; +} +FX_BOOL CGdiDeviceDriver::GDI_StretchDIBits(const CFX_DIBitmap* pBitmap1, + int dest_left, + int dest_top, + int dest_width, + int dest_height, + FX_DWORD flags, + void* pIccTransform) { + CFX_DIBitmap* pBitmap = (CFX_DIBitmap*)pBitmap1; + if (pBitmap == NULL || dest_width == 0 || dest_height == 0) { + return FALSE; + } + if ((pBitmap->IsCmykImage() || pIccTransform) && + !pBitmap->ConvertFormat(FXDIB_Rgb, pIccTransform)) { + return FALSE; + } + CFX_ByteString info = CFX_WindowsDIB::GetBitmapInfo(pBitmap); + if ((int64_t)abs(dest_width) * abs(dest_height) < + (int64_t)pBitmap1->GetWidth() * pBitmap1->GetHeight() * 4 || + (flags & FXDIB_INTERPOL) || (flags & FXDIB_BICUBIC_INTERPOL)) { + SetStretchBltMode(m_hDC, HALFTONE); + } else { + SetStretchBltMode(m_hDC, COLORONCOLOR); + } + CFX_DIBitmap* pToStrechBitmap = pBitmap; + bool del = false; + if (m_DeviceClass == FXDC_PRINTER && + ((int64_t)pBitmap->GetWidth() * pBitmap->GetHeight() > + (int64_t)abs(dest_width) * abs(dest_height))) { + pToStrechBitmap = pBitmap->StretchTo(dest_width, dest_height); + del = true; + } + CFX_ByteString toStrechBitmapInfo = + CFX_WindowsDIB::GetBitmapInfo(pToStrechBitmap); + ::StretchDIBits(m_hDC, dest_left, dest_top, dest_width, dest_height, 0, 0, + pToStrechBitmap->GetWidth(), pToStrechBitmap->GetHeight(), + pToStrechBitmap->GetBuffer(), + (BITMAPINFO*)toStrechBitmapInfo.c_str(), DIB_RGB_COLORS, + SRCCOPY); + if (del) { + delete pToStrechBitmap; + } + return TRUE; +} +FX_BOOL CGdiDeviceDriver::GDI_StretchBitMask(const CFX_DIBitmap* pBitmap1, + int dest_left, + int dest_top, + int dest_width, + int dest_height, + FX_DWORD bitmap_color, + FX_DWORD flags, + int alpha_flag, + void* pIccTransform) { + CFX_DIBitmap* pBitmap = (CFX_DIBitmap*)pBitmap1; + if (pBitmap == NULL || dest_width == 0 || dest_height == 0) { + return FALSE; + } + _Color2Argb(bitmap_color, bitmap_color, alpha_flag | (1 << 24), + pIccTransform); + int width = pBitmap->GetWidth(), height = pBitmap->GetHeight(); + struct { + BITMAPINFOHEADER bmiHeader; + FX_DWORD bmiColors[2]; + } bmi; + FXSYS_memset(&bmi.bmiHeader, 0, sizeof(BITMAPINFOHEADER)); + bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmi.bmiHeader.biBitCount = 1; + bmi.bmiHeader.biCompression = BI_RGB; + bmi.bmiHeader.biHeight = -height; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biWidth = width; + if (m_nBitsPerPixel != 1) { + SetStretchBltMode(m_hDC, HALFTONE); + } + bmi.bmiColors[0] = 0xffffff; + bmi.bmiColors[1] = 0; + HBRUSH hPattern = CreateSolidBrush(bitmap_color & 0xffffff); + HBRUSH hOld = (HBRUSH)SelectObject(m_hDC, hPattern); - // In PDF, when image mask is 1, use device bitmap; when mask is 0, use brush bitmap. - // A complete list of the boolen operations is as follows: + // In PDF, when image mask is 1, use device bitmap; when mask is 0, use brush + // bitmap. + // A complete list of the boolen operations is as follows: - /* P(bitmap_color) S(ImageMask) D(DeviceBitmap) Result - * 0 0 0 0 - * 0 0 1 0 - * 0 1 0 0 - * 0 1 1 1 - * 1 0 0 1 - * 1 0 1 1 - * 1 1 0 0 - * 1 1 1 1 - */ - // The boolen codes is B8. Based on http://msdn.microsoft.com/en-us/library/aa932106.aspx, the ROP3 code is 0xB8074A + /* P(bitmap_color) S(ImageMask) D(DeviceBitmap) Result + * 0 0 0 0 + * 0 0 1 0 + * 0 1 0 0 + * 0 1 1 1 + * 1 0 0 1 + * 1 0 1 1 + * 1 1 0 0 + * 1 1 1 1 + */ + // The boolen codes is B8. Based on + // http://msdn.microsoft.com/en-us/library/aa932106.aspx, the ROP3 code is + // 0xB8074A - ::StretchDIBits(m_hDC, dest_left, dest_top, dest_width, dest_height, - 0, 0, width, height, pBitmap->GetBuffer(), (BITMAPINFO*)&bmi, DIB_RGB_COLORS, 0xB8074A); + ::StretchDIBits(m_hDC, dest_left, dest_top, dest_width, dest_height, 0, 0, + width, height, pBitmap->GetBuffer(), (BITMAPINFO*)&bmi, + DIB_RGB_COLORS, 0xB8074A); - SelectObject(m_hDC, hOld); - DeleteObject(hPattern); + SelectObject(m_hDC, hOld); + DeleteObject(hPattern); - return TRUE; + return TRUE; } -FX_BOOL CGdiDeviceDriver::GetClipBox(FX_RECT* pRect) -{ - return ::GetClipBox(m_hDC, (RECT*)pRect); +FX_BOOL CGdiDeviceDriver::GetClipBox(FX_RECT* pRect) { + return ::GetClipBox(m_hDC, (RECT*)pRect); } -FX_BOOL CGdiDeviceDriver::SetClipRgn(void* hRgn) -{ - ::SelectClipRgn(m_hDC, (HRGN)hRgn); - return TRUE; +FX_BOOL CGdiDeviceDriver::SetClipRgn(void* hRgn) { + ::SelectClipRgn(m_hDC, (HRGN)hRgn); + return TRUE; } -static HPEN _CreatePen(const CFX_GraphStateData* pGraphState, const CFX_AffineMatrix* pMatrix, FX_DWORD argb) -{ - FX_FLOAT width; - FX_FLOAT scale = 1.f; - if (pMatrix) - scale = FXSYS_fabs(pMatrix->a) > FXSYS_fabs(pMatrix->b) ? - FXSYS_fabs(pMatrix->a) : FXSYS_fabs(pMatrix->b); - if (pGraphState) { - width = scale * pGraphState->m_LineWidth; - } else { - width = 1.0f; - } - FX_DWORD PenStyle = PS_GEOMETRIC; - if (width < 1) { - width = 1; - } - if(pGraphState->m_DashCount) { - PenStyle |= PS_USERSTYLE; - } else { - PenStyle |= PS_SOLID; - } - switch(pGraphState->m_LineCap) { - case 0: - PenStyle |= PS_ENDCAP_FLAT; - break; - case 1: - PenStyle |= PS_ENDCAP_ROUND; - break; - case 2: - PenStyle |= PS_ENDCAP_SQUARE; - break; - } - switch(pGraphState->m_LineJoin) { - case 0: - PenStyle |= PS_JOIN_MITER; - break; - case 1: - PenStyle |= PS_JOIN_ROUND; - break; - case 2: - PenStyle |= PS_JOIN_BEVEL; - break; - } - int a; - FX_COLORREF rgb; - ArgbDecode(argb, a, rgb); - LOGBRUSH lb; - lb.lbColor = rgb; - lb.lbStyle = BS_SOLID; - lb.lbHatch = 0; - FX_DWORD* pDash = NULL; - if (pGraphState->m_DashCount) { - pDash = FX_Alloc(FX_DWORD, pGraphState->m_DashCount); - for (int i = 0; i < pGraphState->m_DashCount; i ++) { - pDash[i] = FXSYS_round(pMatrix ? pMatrix->TransformDistance(pGraphState->m_DashArray[i]) : pGraphState->m_DashArray[i]); - if (pDash[i] < 1) { - pDash[i] = 1; - } - } - } - HPEN hPen = ExtCreatePen(PenStyle, (DWORD)FXSYS_ceil(width), &lb, pGraphState->m_DashCount, (const DWORD*)pDash); - if (pDash) { - FX_Free(pDash); - } - return hPen; +static HPEN _CreatePen(const CFX_GraphStateData* pGraphState, + const CFX_AffineMatrix* pMatrix, + FX_DWORD argb) { + FX_FLOAT width; + FX_FLOAT scale = 1.f; + if (pMatrix) + scale = FXSYS_fabs(pMatrix->a) > FXSYS_fabs(pMatrix->b) + ? FXSYS_fabs(pMatrix->a) + : FXSYS_fabs(pMatrix->b); + if (pGraphState) { + width = scale * pGraphState->m_LineWidth; + } else { + width = 1.0f; + } + FX_DWORD PenStyle = PS_GEOMETRIC; + if (width < 1) { + width = 1; + } + if (pGraphState->m_DashCount) { + PenStyle |= PS_USERSTYLE; + } else { + PenStyle |= PS_SOLID; + } + switch (pGraphState->m_LineCap) { + case 0: + PenStyle |= PS_ENDCAP_FLAT; + break; + case 1: + PenStyle |= PS_ENDCAP_ROUND; + break; + case 2: + PenStyle |= PS_ENDCAP_SQUARE; + break; + } + switch (pGraphState->m_LineJoin) { + case 0: + PenStyle |= PS_JOIN_MITER; + break; + case 1: + PenStyle |= PS_JOIN_ROUND; + break; + case 2: + PenStyle |= PS_JOIN_BEVEL; + break; + } + int a; + FX_COLORREF rgb; + ArgbDecode(argb, a, rgb); + LOGBRUSH lb; + lb.lbColor = rgb; + lb.lbStyle = BS_SOLID; + lb.lbHatch = 0; + FX_DWORD* pDash = NULL; + if (pGraphState->m_DashCount) { + pDash = FX_Alloc(FX_DWORD, pGraphState->m_DashCount); + for (int i = 0; i < pGraphState->m_DashCount; i++) { + pDash[i] = FXSYS_round( + pMatrix ? pMatrix->TransformDistance(pGraphState->m_DashArray[i]) + : pGraphState->m_DashArray[i]); + if (pDash[i] < 1) { + pDash[i] = 1; + } + } + } + HPEN hPen = ExtCreatePen(PenStyle, (DWORD)FXSYS_ceil(width), &lb, + pGraphState->m_DashCount, (const DWORD*)pDash); + if (pDash) { + FX_Free(pDash); + } + return hPen; } -static HBRUSH _CreateBrush(FX_DWORD argb) -{ - int a; - FX_COLORREF rgb; - ArgbDecode(argb, a, rgb); - return CreateSolidBrush(rgb); +static HBRUSH _CreateBrush(FX_DWORD argb) { + int a; + FX_COLORREF rgb; + ArgbDecode(argb, a, rgb); + return CreateSolidBrush(rgb); } -static void _SetPathToDC(HDC hDC, const CFX_PathData* pPathData, const CFX_AffineMatrix* pMatrix) -{ - BeginPath(hDC); - int nPoints = pPathData->GetPointCount(); - FX_PATHPOINT* pPoints = pPathData->GetPoints(); - for(int i = 0; i < nPoints; i++) { - FX_FLOAT posx = pPoints[i].m_PointX, posy = pPoints[i].m_PointY; - if (pMatrix) { - pMatrix->Transform(posx, posy); - } - int screen_x = FXSYS_round(posx), screen_y = FXSYS_round(posy); - int point_type = pPoints[i].m_Flag & FXPT_TYPE; - if(point_type == PT_MOVETO) { - MoveToEx(hDC, screen_x, screen_y, NULL); - } else if(point_type == PT_LINETO) { - if (pPoints[i].m_PointY == pPoints[i - 1].m_PointY && pPoints[i].m_PointX == pPoints[i - 1].m_PointX) { - screen_x ++; - } - LineTo(hDC, screen_x, screen_y); - } else if(point_type == PT_BEZIERTO) { - POINT lppt[3]; - lppt[0].x = screen_x; - lppt[0].y = screen_y; - posx = pPoints[i + 1].m_PointX; - posy = pPoints[i + 1].m_PointY; - if (pMatrix) { - pMatrix->Transform(posx, posy); - } - lppt[1].x = FXSYS_round(posx); - lppt[1].y = FXSYS_round(posy); - posx = pPoints[i + 2].m_PointX; - posy = pPoints[i + 2].m_PointY; - if (pMatrix) { - pMatrix->Transform(posx, posy); - } - lppt[2].x = FXSYS_round(posx); - lppt[2].y = FXSYS_round(posy); - PolyBezierTo(hDC, lppt, 3); - i += 2; - } - if (pPoints[i].m_Flag & PT_CLOSEFIGURE) { - CloseFigure(hDC); - } - } - EndPath(hDC); +static void _SetPathToDC(HDC hDC, + const CFX_PathData* pPathData, + const CFX_AffineMatrix* pMatrix) { + BeginPath(hDC); + int nPoints = pPathData->GetPointCount(); + FX_PATHPOINT* pPoints = pPathData->GetPoints(); + for (int i = 0; i < nPoints; i++) { + FX_FLOAT posx = pPoints[i].m_PointX, posy = pPoints[i].m_PointY; + if (pMatrix) { + pMatrix->Transform(posx, posy); + } + int screen_x = FXSYS_round(posx), screen_y = FXSYS_round(posy); + int point_type = pPoints[i].m_Flag & FXPT_TYPE; + if (point_type == PT_MOVETO) { + MoveToEx(hDC, screen_x, screen_y, NULL); + } else if (point_type == PT_LINETO) { + if (pPoints[i].m_PointY == pPoints[i - 1].m_PointY && + pPoints[i].m_PointX == pPoints[i - 1].m_PointX) { + screen_x++; + } + LineTo(hDC, screen_x, screen_y); + } else if (point_type == PT_BEZIERTO) { + POINT lppt[3]; + lppt[0].x = screen_x; + lppt[0].y = screen_y; + posx = pPoints[i + 1].m_PointX; + posy = pPoints[i + 1].m_PointY; + if (pMatrix) { + pMatrix->Transform(posx, posy); + } + lppt[1].x = FXSYS_round(posx); + lppt[1].y = FXSYS_round(posy); + posx = pPoints[i + 2].m_PointX; + posy = pPoints[i + 2].m_PointY; + if (pMatrix) { + pMatrix->Transform(posx, posy); + } + lppt[2].x = FXSYS_round(posx); + lppt[2].y = FXSYS_round(posy); + PolyBezierTo(hDC, lppt, 3); + i += 2; + } + if (pPoints[i].m_Flag & PT_CLOSEFIGURE) { + CloseFigure(hDC); + } + } + EndPath(hDC); } -void CGdiDeviceDriver::DrawLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2) -{ - int flag1 = (x1 < 0) | ((x1 > m_Width) << 1) | ((y1 < 0) << 2) | ((y1 > m_Height) << 3); - int flag2 = (x2 < 0) | ((x2 > m_Width) << 1) | ((y2 < 0) << 2) | ((y2 > m_Height) << 3); - if (flag1 & flag2) { - return; - } - if (flag1 || flag2) { - agg::rect_base rect(0.0f, 0.0f, (FX_FLOAT)(m_Width), (FX_FLOAT)(m_Height)); - FX_FLOAT x[2], y[2]; - int np = agg::clip_liang_barsky(x1, y1, x2, y2, rect, x, y); - if (np == 0) { - return; - } - if (np == 1) { - x2 = x[0]; - y2 = y[0]; - } else { - x1 = x[0]; - y1 = y[0]; - x2 = x[np - 1]; - y2 = y[np - 1]; - } - } - MoveToEx(m_hDC, FXSYS_round(x1), FXSYS_round(y1), NULL); - LineTo(m_hDC, FXSYS_round(x2), FXSYS_round(y2)); +void CGdiDeviceDriver::DrawLine(FX_FLOAT x1, + FX_FLOAT y1, + FX_FLOAT x2, + FX_FLOAT y2) { + int flag1 = (x1 < 0) | ((x1 > m_Width) << 1) | ((y1 < 0) << 2) | + ((y1 > m_Height) << 3); + int flag2 = (x2 < 0) | ((x2 > m_Width) << 1) | ((y2 < 0) << 2) | + ((y2 > m_Height) << 3); + if (flag1 & flag2) { + return; + } + if (flag1 || flag2) { + agg::rect_base rect(0.0f, 0.0f, (FX_FLOAT)(m_Width), + (FX_FLOAT)(m_Height)); + FX_FLOAT x[2], y[2]; + int np = agg::clip_liang_barsky(x1, y1, x2, y2, rect, x, y); + if (np == 0) { + return; + } + if (np == 1) { + x2 = x[0]; + y2 = y[0]; + } else { + x1 = x[0]; + y1 = y[0]; + x2 = x[np - 1]; + y2 = y[np - 1]; + } + } + MoveToEx(m_hDC, FXSYS_round(x1), FXSYS_round(y1), NULL); + LineTo(m_hDC, FXSYS_round(x2), FXSYS_round(y2)); } -static FX_BOOL _MatrixNoScaled(const CFX_AffineMatrix* pMatrix) -{ - return pMatrix->GetA() == 1.0f && pMatrix->GetB() == 0 && pMatrix->GetC() == 0 && pMatrix->GetD() == 1.0f; +static FX_BOOL _MatrixNoScaled(const CFX_AffineMatrix* pMatrix) { + return pMatrix->GetA() == 1.0f && pMatrix->GetB() == 0 && + pMatrix->GetC() == 0 && pMatrix->GetD() == 1.0f; } FX_BOOL CGdiDeviceDriver::DrawPath(const CFX_PathData* pPathData, const CFX_AffineMatrix* pMatrix, @@ -761,446 +798,519 @@ FX_BOOL CGdiDeviceDriver::DrawPath(const CFX_PathData* pPathData, int fill_mode, int alpha_flag, void* pIccTransform, - int blend_type - ) -{ - 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); - CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData(); - if ((pGraphState == NULL || stroke_color == 0) && !pPlatform->m_GdiplusExt.IsAvailable()) { - CFX_FloatRect bbox_f = pPathData->GetBoundingBox(); - if (pMatrix) { - bbox_f.Transform(pMatrix); - } - FX_RECT bbox = bbox_f.GetInnerRect(); - if (bbox.Width() <= 0) { - return DrawCosmeticLine((FX_FLOAT)(bbox.left), (FX_FLOAT)(bbox.top), (FX_FLOAT)(bbox.left), (FX_FLOAT)(bbox.bottom + 1), fill_color, - alpha_flag, pIccTransform, FXDIB_BLEND_NORMAL); - } else if (bbox.Height() <= 0) { - return DrawCosmeticLine((FX_FLOAT)(bbox.left), (FX_FLOAT)(bbox.top), (FX_FLOAT)(bbox.right + 1), (FX_FLOAT)(bbox.top), fill_color, - alpha_flag, pIccTransform, FXDIB_BLEND_NORMAL); - } - } - int fill_alpha = FXARGB_A(fill_color); - int stroke_alpha = FXARGB_A(stroke_color); - FX_BOOL bDrawAlpha = (fill_alpha > 0 && fill_alpha < 255) || (stroke_alpha > 0 && stroke_alpha < 255 && pGraphState); - if (!pPlatform->m_GdiplusExt.IsAvailable() && bDrawAlpha) { - return FALSE; - } - if (pPlatform->m_GdiplusExt.IsAvailable()) { - if (bDrawAlpha || ((m_DeviceClass != FXDC_PRINTER && !(fill_mode & FXFILL_FULLCOVER)) || (pGraphState && pGraphState->m_DashCount))) { - if ( !((NULL == pMatrix || _MatrixNoScaled(pMatrix)) && - pGraphState && pGraphState->m_LineWidth == 1.f && - (pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) && - pPathData->IsRect()) ) { - if (pPlatform->m_GdiplusExt.DrawPath(m_hDC, pPathData, pMatrix, pGraphState, fill_color, stroke_color, fill_mode)) { - return TRUE; - } - } + int blend_type) { + 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); + CWin32Platform* pPlatform = + (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData(); + if ((pGraphState == NULL || stroke_color == 0) && + !pPlatform->m_GdiplusExt.IsAvailable()) { + CFX_FloatRect bbox_f = pPathData->GetBoundingBox(); + if (pMatrix) { + bbox_f.Transform(pMatrix); + } + FX_RECT bbox = bbox_f.GetInnerRect(); + if (bbox.Width() <= 0) { + return DrawCosmeticLine((FX_FLOAT)(bbox.left), (FX_FLOAT)(bbox.top), + (FX_FLOAT)(bbox.left), + (FX_FLOAT)(bbox.bottom + 1), fill_color, + alpha_flag, pIccTransform, FXDIB_BLEND_NORMAL); + } else if (bbox.Height() <= 0) { + return DrawCosmeticLine((FX_FLOAT)(bbox.left), (FX_FLOAT)(bbox.top), + (FX_FLOAT)(bbox.right + 1), (FX_FLOAT)(bbox.top), + fill_color, alpha_flag, pIccTransform, + FXDIB_BLEND_NORMAL); + } + } + int fill_alpha = FXARGB_A(fill_color); + int stroke_alpha = FXARGB_A(stroke_color); + FX_BOOL bDrawAlpha = (fill_alpha > 0 && fill_alpha < 255) || + (stroke_alpha > 0 && stroke_alpha < 255 && pGraphState); + if (!pPlatform->m_GdiplusExt.IsAvailable() && bDrawAlpha) { + return FALSE; + } + if (pPlatform->m_GdiplusExt.IsAvailable()) { + if (bDrawAlpha || + ((m_DeviceClass != FXDC_PRINTER && !(fill_mode & FXFILL_FULLCOVER)) || + (pGraphState && pGraphState->m_DashCount))) { + if (!((NULL == pMatrix || _MatrixNoScaled(pMatrix)) && pGraphState && + pGraphState->m_LineWidth == 1.f && + (pPathData->GetPointCount() == 5 || + pPathData->GetPointCount() == 4) && + pPathData->IsRect())) { + if (pPlatform->m_GdiplusExt.DrawPath(m_hDC, pPathData, pMatrix, + pGraphState, fill_color, + stroke_color, fill_mode)) { + return TRUE; } - } - int old_fill_mode = fill_mode; - fill_mode &= 3; - HPEN hPen = NULL; - HBRUSH hBrush = NULL; + } + } + } + int old_fill_mode = fill_mode; + fill_mode &= 3; + HPEN hPen = NULL; + HBRUSH hBrush = NULL; + if (pGraphState && stroke_alpha) { + SetMiterLimit(m_hDC, pGraphState->m_MiterLimit, NULL); + hPen = _CreatePen(pGraphState, pMatrix, stroke_color); + hPen = (HPEN)SelectObject(m_hDC, hPen); + } + if (fill_mode && fill_alpha) { + SetPolyFillMode(m_hDC, fill_mode); + hBrush = _CreateBrush(fill_color); + hBrush = (HBRUSH)SelectObject(m_hDC, hBrush); + } + if (pPathData->GetPointCount() == 2 && pGraphState && + pGraphState->m_DashCount) { + FX_FLOAT x1 = pPathData->GetPointX(0), y1 = pPathData->GetPointY(0); + if (pMatrix) { + pMatrix->Transform(x1, y1); + } + FX_FLOAT x2 = pPathData->GetPointX(1), y2 = pPathData->GetPointY(1); + if (pMatrix) { + pMatrix->Transform(x2, y2); + } + DrawLine(x1, y1, x2, y2); + } else { + _SetPathToDC(m_hDC, pPathData, pMatrix); if (pGraphState && stroke_alpha) { - SetMiterLimit(m_hDC, pGraphState->m_MiterLimit, NULL); - hPen = _CreatePen(pGraphState, pMatrix, stroke_color); - hPen = (HPEN)SelectObject(m_hDC, hPen); - } - if (fill_mode && fill_alpha) { - SetPolyFillMode(m_hDC, fill_mode); - hBrush = _CreateBrush(fill_color); - hBrush = (HBRUSH)SelectObject(m_hDC, hBrush); - } - if (pPathData->GetPointCount() == 2 && pGraphState && pGraphState->m_DashCount) { - FX_FLOAT x1 = pPathData->GetPointX(0), y1 = pPathData->GetPointY(0); - if (pMatrix) { - pMatrix->Transform(x1, y1); - } - FX_FLOAT x2 = pPathData->GetPointX(1), y2 = pPathData->GetPointY(1); - if (pMatrix) { - pMatrix->Transform(x2, y2); - } - DrawLine(x1, y1, x2, y2); - } else { - _SetPathToDC(m_hDC, pPathData, pMatrix); - if (pGraphState && stroke_alpha) { - if (fill_mode && fill_alpha) { - if (old_fill_mode & FX_FILL_TEXT_MODE) { - StrokeAndFillPath(m_hDC); - } else { - FillPath(m_hDC); - _SetPathToDC(m_hDC, pPathData, pMatrix); - StrokePath(m_hDC); - } - } else { - StrokePath(m_hDC); - } - } else if (fill_mode && fill_alpha) { - FillPath(m_hDC); + if (fill_mode && fill_alpha) { + if (old_fill_mode & FX_FILL_TEXT_MODE) { + StrokeAndFillPath(m_hDC); + } else { + FillPath(m_hDC); + _SetPathToDC(m_hDC, pPathData, pMatrix); + StrokePath(m_hDC); } - } - if (hPen) { - hPen = (HPEN)SelectObject(m_hDC, hPen); - DeleteObject(hPen); - } - if (hBrush) { - hBrush = (HBRUSH)SelectObject(m_hDC, hBrush); - DeleteObject(hBrush); - } - return TRUE; -} -FX_BOOL CGdiDeviceDriver::FillRect(const FX_RECT* pRect, FX_DWORD fill_color, int alpha_flag, void* pIccTransform, int blend_type) -{ - if (blend_type != FXDIB_BLEND_NORMAL) { - return FALSE; - } - _Color2Argb(fill_color, fill_color, alpha_flag | (1 << 24), pIccTransform); - int alpha; - FX_COLORREF rgb; - ArgbDecode(fill_color, alpha, rgb); - if (alpha == 0) { - return TRUE; - } - if (alpha < 255) { - return FALSE; - } - HBRUSH hBrush = CreateSolidBrush(rgb); - ::FillRect(m_hDC, (RECT*)pRect, hBrush); + } else { + StrokePath(m_hDC); + } + } else if (fill_mode && fill_alpha) { + FillPath(m_hDC); + } + } + if (hPen) { + hPen = (HPEN)SelectObject(m_hDC, hPen); + DeleteObject(hPen); + } + if (hBrush) { + hBrush = (HBRUSH)SelectObject(m_hDC, hBrush); DeleteObject(hBrush); + } + return TRUE; +} +FX_BOOL CGdiDeviceDriver::FillRect(const FX_RECT* pRect, + FX_DWORD fill_color, + int alpha_flag, + void* pIccTransform, + int blend_type) { + if (blend_type != FXDIB_BLEND_NORMAL) { + return FALSE; + } + _Color2Argb(fill_color, fill_color, alpha_flag | (1 << 24), pIccTransform); + int alpha; + FX_COLORREF rgb; + ArgbDecode(fill_color, alpha, rgb); + if (alpha == 0) { return TRUE; + } + if (alpha < 255) { + return FALSE; + } + HBRUSH hBrush = CreateSolidBrush(rgb); + ::FillRect(m_hDC, (RECT*)pRect, hBrush); + DeleteObject(hBrush); + return TRUE; } FX_BOOL CGdiDeviceDriver::SetClip_PathFill(const CFX_PathData* pPathData, - const CFX_AffineMatrix* pMatrix, - int fill_mode - ) -{ - if (pPathData->GetPointCount() == 5) { - CFX_FloatRect rectf; - if (pPathData->IsRect(pMatrix, &rectf)) { - FX_RECT rect = rectf.GetOutterRect(); - IntersectClipRect(m_hDC, rect.left, rect.top, rect.right, rect.bottom); - return TRUE; - } - } - _SetPathToDC(m_hDC, pPathData, pMatrix); - SetPolyFillMode(m_hDC, fill_mode & 3); - SelectClipPath(m_hDC, RGN_AND); - return TRUE; + const CFX_AffineMatrix* pMatrix, + int fill_mode) { + if (pPathData->GetPointCount() == 5) { + CFX_FloatRect rectf; + if (pPathData->IsRect(pMatrix, &rectf)) { + FX_RECT rect = rectf.GetOutterRect(); + IntersectClipRect(m_hDC, rect.left, rect.top, rect.right, rect.bottom); + return TRUE; + } + } + _SetPathToDC(m_hDC, pPathData, pMatrix); + SetPolyFillMode(m_hDC, fill_mode & 3); + SelectClipPath(m_hDC, RGN_AND); + return TRUE; } -FX_BOOL CGdiDeviceDriver::SetClip_PathStroke(const CFX_PathData* pPathData, - const CFX_AffineMatrix* pMatrix, - const CFX_GraphStateData* pGraphState - ) -{ - HPEN hPen = _CreatePen(pGraphState, pMatrix, 0xff000000); - hPen = (HPEN)SelectObject(m_hDC, hPen); - _SetPathToDC(m_hDC, pPathData, pMatrix); - WidenPath(m_hDC); - SetPolyFillMode(m_hDC, WINDING); - FX_BOOL ret = SelectClipPath(m_hDC, RGN_AND); - hPen = (HPEN)SelectObject(m_hDC, hPen); - DeleteObject(hPen); - return ret; +FX_BOOL CGdiDeviceDriver::SetClip_PathStroke( + const CFX_PathData* pPathData, + const CFX_AffineMatrix* pMatrix, + const CFX_GraphStateData* pGraphState) { + HPEN hPen = _CreatePen(pGraphState, pMatrix, 0xff000000); + hPen = (HPEN)SelectObject(m_hDC, hPen); + _SetPathToDC(m_hDC, pPathData, pMatrix); + WidenPath(m_hDC); + SetPolyFillMode(m_hDC, WINDING); + FX_BOOL ret = SelectClipPath(m_hDC, RGN_AND); + hPen = (HPEN)SelectObject(m_hDC, hPen); + DeleteObject(hPen); + return ret; } -FX_BOOL CGdiDeviceDriver::DrawCosmeticLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2, FX_DWORD color, - int alpha_flag, void* pIccTransform, int blend_type) -{ - if (blend_type != FXDIB_BLEND_NORMAL) { - return FALSE; - } - _Color2Argb(color, color, alpha_flag | (1 << 24), pIccTransform); - int a; - FX_COLORREF rgb; - ArgbDecode(color, a, rgb); - if (a == 0) { - return TRUE; - } - HPEN hPen = CreatePen(PS_SOLID, 1, rgb); - hPen = (HPEN)SelectObject(m_hDC, hPen); - MoveToEx(m_hDC, FXSYS_round(x1), FXSYS_round(y1), NULL); - LineTo(m_hDC, FXSYS_round(x2), FXSYS_round(y2)); - hPen = (HPEN)SelectObject(m_hDC, hPen); - DeleteObject(hPen); +FX_BOOL CGdiDeviceDriver::DrawCosmeticLine(FX_FLOAT x1, + FX_FLOAT y1, + FX_FLOAT x2, + FX_FLOAT y2, + FX_DWORD color, + int alpha_flag, + void* pIccTransform, + int blend_type) { + if (blend_type != FXDIB_BLEND_NORMAL) { + return FALSE; + } + _Color2Argb(color, color, alpha_flag | (1 << 24), pIccTransform); + int a; + FX_COLORREF rgb; + ArgbDecode(color, a, rgb); + if (a == 0) { return TRUE; + } + HPEN hPen = CreatePen(PS_SOLID, 1, rgb); + hPen = (HPEN)SelectObject(m_hDC, hPen); + MoveToEx(m_hDC, FXSYS_round(x1), FXSYS_round(y1), NULL); + LineTo(m_hDC, FXSYS_round(x2), FXSYS_round(y2)); + hPen = (HPEN)SelectObject(m_hDC, hPen); + DeleteObject(hPen); + return TRUE; } -FX_BOOL CGdiDeviceDriver::DeleteDeviceRgn(void* pRgn) -{ - DeleteObject((HGDIOBJ)pRgn); - return TRUE; +FX_BOOL CGdiDeviceDriver::DeleteDeviceRgn(void* pRgn) { + DeleteObject((HGDIOBJ)pRgn); + return TRUE; } -CGdiDisplayDriver::CGdiDisplayDriver(HDC hDC) : CGdiDeviceDriver(hDC, FXDC_DISPLAY) -{ - CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData(); - if (pPlatform->m_GdiplusExt.IsAvailable()) { - m_RenderCaps |= FXRC_ALPHA_PATH | FXRC_ALPHA_IMAGE; - } +CGdiDisplayDriver::CGdiDisplayDriver(HDC hDC) + : CGdiDeviceDriver(hDC, FXDC_DISPLAY) { + CWin32Platform* pPlatform = + (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData(); + if (pPlatform->m_GdiplusExt.IsAvailable()) { + m_RenderCaps |= FXRC_ALPHA_PATH | FXRC_ALPHA_IMAGE; + } } -FX_BOOL CGdiDisplayDriver::GetDIBits(CFX_DIBitmap* pBitmap, int left, int top, void* pIccTransform, FX_BOOL bDEdge) -{ - FX_BOOL ret = FALSE; - int width = pBitmap->GetWidth(); - int height = pBitmap->GetHeight(); - HBITMAP hbmp = CreateCompatibleBitmap(m_hDC, width, height); - HDC hDCMemory = CreateCompatibleDC(m_hDC); - HBITMAP holdbmp = (HBITMAP)SelectObject(hDCMemory, hbmp); - BitBlt(hDCMemory, 0, 0, width, height, m_hDC, left, top, SRCCOPY); - SelectObject(hDCMemory, holdbmp); - BITMAPINFO bmi; - FXSYS_memset(&bmi, 0, sizeof bmi); - bmi.bmiHeader.biSize = sizeof bmi.bmiHeader; - bmi.bmiHeader.biBitCount = pBitmap->GetBPP(); - bmi.bmiHeader.biHeight = -height; - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biWidth = width; - if (!CFX_GEModule::Get()->GetCodecModule() || !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) { - pIccTransform = NULL; - } - if (pBitmap->GetBPP() > 8 && !pBitmap->IsCmykImage() && pIccTransform == NULL) { - ret = ::GetDIBits(hDCMemory, hbmp, 0, height, pBitmap->GetBuffer(), &bmi, DIB_RGB_COLORS) == height; +FX_BOOL CGdiDisplayDriver::GetDIBits(CFX_DIBitmap* pBitmap, + int left, + int top, + void* pIccTransform, + FX_BOOL bDEdge) { + FX_BOOL ret = FALSE; + int width = pBitmap->GetWidth(); + int height = pBitmap->GetHeight(); + HBITMAP hbmp = CreateCompatibleBitmap(m_hDC, width, height); + HDC hDCMemory = CreateCompatibleDC(m_hDC); + HBITMAP holdbmp = (HBITMAP)SelectObject(hDCMemory, hbmp); + BitBlt(hDCMemory, 0, 0, width, height, m_hDC, left, top, SRCCOPY); + SelectObject(hDCMemory, holdbmp); + BITMAPINFO bmi; + FXSYS_memset(&bmi, 0, sizeof bmi); + bmi.bmiHeader.biSize = sizeof bmi.bmiHeader; + bmi.bmiHeader.biBitCount = pBitmap->GetBPP(); + bmi.bmiHeader.biHeight = -height; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biWidth = width; + if (!CFX_GEModule::Get()->GetCodecModule() || + !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) { + pIccTransform = NULL; + } + if (pBitmap->GetBPP() > 8 && !pBitmap->IsCmykImage() && + pIccTransform == NULL) { + ret = ::GetDIBits(hDCMemory, hbmp, 0, height, pBitmap->GetBuffer(), &bmi, + DIB_RGB_COLORS) == height; + } else { + CFX_DIBitmap bitmap; + if (bitmap.Create(width, height, FXDIB_Rgb)) { + bmi.bmiHeader.biBitCount = 24; + ::GetDIBits(hDCMemory, hbmp, 0, height, bitmap.GetBuffer(), &bmi, + DIB_RGB_COLORS); + ret = pBitmap->TransferBitmap(0, 0, width, height, &bitmap, 0, 0, + pIccTransform); } else { - CFX_DIBitmap bitmap; - if (bitmap.Create(width, height, FXDIB_Rgb)) { - bmi.bmiHeader.biBitCount = 24; - ::GetDIBits(hDCMemory, hbmp, 0, height, bitmap.GetBuffer(), &bmi, DIB_RGB_COLORS); - ret = pBitmap->TransferBitmap(0, 0, width, height, &bitmap, 0, 0, pIccTransform); - } else { - ret = FALSE; - } - } - if (pBitmap->HasAlpha() && ret) { - pBitmap->LoadChannel(FXDIB_Alpha, 0xff); - } - DeleteObject(hbmp); - DeleteObject(hDCMemory); - return ret; + ret = FALSE; + } + } + if (pBitmap->HasAlpha() && ret) { + pBitmap->LoadChannel(FXDIB_Alpha, 0xff); + } + DeleteObject(hbmp); + DeleteObject(hDCMemory); + return ret; } -FX_BOOL CGdiDisplayDriver::SetDIBits(const CFX_DIBSource* pSource, FX_DWORD color, const FX_RECT* pSrcRect, int left, int top, int blend_type, - int alpha_flag, void* pIccTransform) -{ - ASSERT(blend_type == FXDIB_BLEND_NORMAL); - if (pSource->IsAlphaMask()) { - int width = pSource->GetWidth(), height = pSource->GetHeight(); - int alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(color); - FX_BOOL bGDI = pSource->GetBPP() == 1 && alpha == 255; - if (!bGDI) { - CFX_DIBitmap background; - if (!background.Create(width, height, FXDIB_Rgb32) || - !GetDIBits(&background, left, top, NULL) || - !background.CompositeMask(0, 0, width, height, pSource, color, - 0, 0, FXDIB_BLEND_NORMAL, NULL, FALSE, - alpha_flag, pIccTransform)) { - return FALSE; - } - FX_RECT src_rect(0, 0, width, height); - return SetDIBits(&background, 0, &src_rect, left, top, FXDIB_BLEND_NORMAL, 0, NULL); - } - FX_RECT clip_rect(left, top, left + pSrcRect->Width(), top + pSrcRect->Height()); - return StretchDIBits(pSource, color, left - pSrcRect->left, top - pSrcRect->top, width, height, - &clip_rect, 0, alpha_flag, pIccTransform, FXDIB_BLEND_NORMAL); - } - int width = pSrcRect->Width(), height = pSrcRect->Height(); - if (pSource->HasAlpha()) { - CFX_DIBitmap bitmap; - if (!bitmap.Create(width, height, FXDIB_Rgb) || - !GetDIBits(&bitmap, left, top, NULL) || - !bitmap.CompositeBitmap(0, 0, width, height, pSource, pSrcRect->left, pSrcRect->top, FXDIB_BLEND_NORMAL, NULL, FALSE, pIccTransform)) { - return FALSE; - } - FX_RECT src_rect(0, 0, width, height); - return SetDIBits(&bitmap, 0, &src_rect, left, top, FXDIB_BLEND_NORMAL, 0, NULL); - } - CFX_DIBExtractor temp(pSource); - CFX_DIBitmap* pBitmap = temp; - if (pBitmap) { - return GDI_SetDIBits(pBitmap, pSrcRect, left, top, pIccTransform); - } - return FALSE; +FX_BOOL CGdiDisplayDriver::SetDIBits(const CFX_DIBSource* pSource, + FX_DWORD color, + const FX_RECT* pSrcRect, + int left, + int top, + int blend_type, + int alpha_flag, + void* pIccTransform) { + ASSERT(blend_type == FXDIB_BLEND_NORMAL); + if (pSource->IsAlphaMask()) { + int width = pSource->GetWidth(), height = pSource->GetHeight(); + int alpha = FXGETFLAG_COLORTYPE(alpha_flag) + ? FXGETFLAG_ALPHA_FILL(alpha_flag) + : FXARGB_A(color); + FX_BOOL bGDI = pSource->GetBPP() == 1 && alpha == 255; + if (!bGDI) { + CFX_DIBitmap background; + if (!background.Create(width, height, FXDIB_Rgb32) || + !GetDIBits(&background, left, top, NULL) || + !background.CompositeMask(0, 0, width, height, pSource, color, 0, 0, + FXDIB_BLEND_NORMAL, NULL, FALSE, alpha_flag, + pIccTransform)) { + return FALSE; + } + FX_RECT src_rect(0, 0, width, height); + return SetDIBits(&background, 0, &src_rect, left, top, FXDIB_BLEND_NORMAL, + 0, NULL); + } + FX_RECT clip_rect(left, top, left + pSrcRect->Width(), + top + pSrcRect->Height()); + return StretchDIBits(pSource, color, left - pSrcRect->left, + top - pSrcRect->top, width, height, &clip_rect, 0, + alpha_flag, pIccTransform, FXDIB_BLEND_NORMAL); + } + int width = pSrcRect->Width(), height = pSrcRect->Height(); + if (pSource->HasAlpha()) { + CFX_DIBitmap bitmap; + if (!bitmap.Create(width, height, FXDIB_Rgb) || + !GetDIBits(&bitmap, left, top, NULL) || + !bitmap.CompositeBitmap(0, 0, width, height, pSource, pSrcRect->left, + pSrcRect->top, FXDIB_BLEND_NORMAL, NULL, FALSE, + pIccTransform)) { + return FALSE; + } + FX_RECT src_rect(0, 0, width, height); + return SetDIBits(&bitmap, 0, &src_rect, left, top, FXDIB_BLEND_NORMAL, 0, + NULL); + } + CFX_DIBExtractor temp(pSource); + CFX_DIBitmap* pBitmap = temp; + if (pBitmap) { + return GDI_SetDIBits(pBitmap, pSrcRect, left, top, pIccTransform); + } + return FALSE; } -FX_BOOL CGdiDisplayDriver::UseFoxitStretchEngine(const CFX_DIBSource* pSource, FX_DWORD color, int dest_left, int dest_top, - int dest_width, int dest_height, const FX_RECT* pClipRect, int render_flags, - int alpha_flag, void* pIccTransform, int blend_type) -{ - FX_RECT bitmap_clip = *pClipRect; - if (dest_width < 0) { - dest_left += dest_width; - } - if (dest_height < 0) { - dest_top += dest_height; - } - bitmap_clip.Offset(-dest_left, -dest_top); - CFX_DIBitmap* pStretched = pSource->StretchTo(dest_width, dest_height, render_flags, &bitmap_clip); +FX_BOOL CGdiDisplayDriver::UseFoxitStretchEngine(const CFX_DIBSource* pSource, + FX_DWORD color, + int dest_left, + int dest_top, + int dest_width, + int dest_height, + const FX_RECT* pClipRect, + int render_flags, + int alpha_flag, + void* pIccTransform, + int blend_type) { + FX_RECT bitmap_clip = *pClipRect; + if (dest_width < 0) { + dest_left += dest_width; + } + if (dest_height < 0) { + dest_top += dest_height; + } + bitmap_clip.Offset(-dest_left, -dest_top); + CFX_DIBitmap* pStretched = + pSource->StretchTo(dest_width, dest_height, render_flags, &bitmap_clip); + if (pStretched == NULL) { + return TRUE; + } + FX_RECT src_rect(0, 0, pStretched->GetWidth(), pStretched->GetHeight()); + FX_BOOL ret = + SetDIBits(pStretched, color, &src_rect, pClipRect->left, pClipRect->top, + FXDIB_BLEND_NORMAL, alpha_flag, pIccTransform); + delete pStretched; + return ret; +} +FX_BOOL CGdiDisplayDriver::StretchDIBits(const CFX_DIBSource* pSource, + FX_DWORD color, + int dest_left, + int dest_top, + int dest_width, + int dest_height, + const FX_RECT* pClipRect, + FX_DWORD flags, + int alpha_flag, + void* pIccTransform, + int blend_type) { + ASSERT(pSource != NULL && pClipRect != NULL); + if (flags || dest_width > 10000 || dest_width < -10000 || + dest_height > 10000 || dest_height < -10000) { + return UseFoxitStretchEngine(pSource, color, dest_left, dest_top, + dest_width, dest_height, pClipRect, flags, + alpha_flag, pIccTransform, blend_type); + } + if (pSource->IsAlphaMask()) { + FX_RECT image_rect; + image_rect.left = dest_width > 0 ? dest_left : dest_left + dest_width; + image_rect.right = dest_width > 0 ? dest_left + dest_width : dest_left; + image_rect.top = dest_height > 0 ? dest_top : dest_top + dest_height; + image_rect.bottom = dest_height > 0 ? dest_top + dest_height : dest_top; + FX_RECT clip_rect = image_rect; + clip_rect.Intersect(*pClipRect); + clip_rect.Offset(-image_rect.left, -image_rect.top); + int clip_width = clip_rect.Width(), clip_height = clip_rect.Height(); + CFX_DIBitmap* pStretched = + pSource->StretchTo(dest_width, dest_height, flags, &clip_rect); if (pStretched == NULL) { - return TRUE; - } - FX_RECT src_rect(0, 0, pStretched->GetWidth(), pStretched->GetHeight()); - FX_BOOL ret = SetDIBits(pStretched, color, &src_rect, pClipRect->left, pClipRect->top, FXDIB_BLEND_NORMAL, alpha_flag, pIccTransform); + return TRUE; + } + CFX_DIBitmap background; + if (!background.Create(clip_width, clip_height, FXDIB_Rgb32) || + !GetDIBits(&background, image_rect.left + clip_rect.left, + image_rect.top + clip_rect.top, NULL) || + !background.CompositeMask(0, 0, clip_width, clip_height, pStretched, + color, 0, 0, FXDIB_BLEND_NORMAL, NULL, FALSE, + alpha_flag, pIccTransform)) { + delete pStretched; + return FALSE; + } + FX_RECT src_rect(0, 0, clip_width, clip_height); + FX_BOOL ret = + SetDIBits(&background, 0, &src_rect, image_rect.left + clip_rect.left, + image_rect.top + clip_rect.top, FXDIB_BLEND_NORMAL, 0, NULL); delete pStretched; return ret; + } + if (pSource->HasAlpha()) { + CWin32Platform* pPlatform = + (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData(); + if (pPlatform->m_GdiplusExt.IsAvailable() && pIccTransform == NULL && + !pSource->IsCmykImage()) { + CFX_DIBExtractor temp(pSource); + CFX_DIBitmap* pBitmap = temp; + if (pBitmap == NULL) { + return FALSE; + } + return pPlatform->m_GdiplusExt.StretchDIBits( + m_hDC, pBitmap, dest_left, dest_top, dest_width, dest_height, + pClipRect, flags); + } + return UseFoxitStretchEngine(pSource, color, dest_left, dest_top, + dest_width, dest_height, pClipRect, flags, + alpha_flag, pIccTransform, blend_type); + } + CFX_DIBExtractor temp(pSource); + CFX_DIBitmap* pBitmap = temp; + if (pBitmap) { + return GDI_StretchDIBits(pBitmap, dest_left, dest_top, dest_width, + dest_height, flags, pIccTransform); + } + return FALSE; } -FX_BOOL CGdiDisplayDriver::StretchDIBits(const CFX_DIBSource* pSource, FX_DWORD color, int dest_left, int dest_top, - int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags, - int alpha_flag, void* pIccTransform, int blend_type) -{ - ASSERT(pSource != NULL && pClipRect != NULL); - if (flags || dest_width > 10000 || dest_width < -10000 || dest_height > 10000 || dest_height < -10000) { - return UseFoxitStretchEngine(pSource, color, dest_left, dest_top, dest_width, dest_height, - pClipRect, flags, alpha_flag, pIccTransform, blend_type); - } - if (pSource->IsAlphaMask()) { - FX_RECT image_rect; - image_rect.left = dest_width > 0 ? dest_left : dest_left + dest_width; - image_rect.right = dest_width > 0 ? dest_left + dest_width : dest_left; - image_rect.top = dest_height > 0 ? dest_top : dest_top + dest_height; - image_rect.bottom = dest_height > 0 ? dest_top + dest_height : dest_top; - FX_RECT clip_rect = image_rect; - clip_rect.Intersect(*pClipRect); - clip_rect.Offset(-image_rect.left, -image_rect.top); - int clip_width = clip_rect.Width(), clip_height = clip_rect.Height(); - CFX_DIBitmap* pStretched = pSource->StretchTo(dest_width, dest_height, flags, &clip_rect); - if (pStretched == NULL) { - return TRUE; - } - CFX_DIBitmap background; - if (!background.Create(clip_width, clip_height, FXDIB_Rgb32) || - !GetDIBits(&background, image_rect.left + clip_rect.left, image_rect.top + clip_rect.top, NULL) || - !background.CompositeMask(0, 0, clip_width, clip_height, pStretched, color, 0, 0, FXDIB_BLEND_NORMAL, NULL, FALSE, alpha_flag, pIccTransform)) { - delete pStretched; - return FALSE; - } - FX_RECT src_rect(0, 0, clip_width, clip_height); - FX_BOOL ret = SetDIBits(&background, 0, &src_rect, image_rect.left + clip_rect.left, image_rect.top + clip_rect.top, FXDIB_BLEND_NORMAL, 0, NULL); - delete pStretched; - return ret; - } - if (pSource->HasAlpha()) { - CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData(); - if (pPlatform->m_GdiplusExt.IsAvailable() && pIccTransform == NULL && !pSource->IsCmykImage()) { - CFX_DIBExtractor temp(pSource); - CFX_DIBitmap* pBitmap = temp; - if (pBitmap == NULL) { - return FALSE; - } - return pPlatform->m_GdiplusExt.StretchDIBits(m_hDC, pBitmap, dest_left, dest_top, dest_width, dest_height, pClipRect, flags); - } - return UseFoxitStretchEngine(pSource, color, dest_left, dest_top, dest_width, dest_height, - pClipRect, flags, alpha_flag, pIccTransform, blend_type); - } - CFX_DIBExtractor temp(pSource); - CFX_DIBitmap* pBitmap = temp; - if (pBitmap) { - return GDI_StretchDIBits(pBitmap, dest_left, dest_top, dest_width, dest_height, flags, pIccTransform); - } - return FALSE; -} -#define GET_PS_FEATURESETTING 4121 -#define FEATURESETTING_PSLEVEL 2 -int GetPSLevel(HDC hDC) -{ - int device_type = ::GetDeviceCaps(hDC, TECHNOLOGY); - if (device_type != DT_RASPRINTER) { - return 0; - } - FX_DWORD esc = GET_PS_FEATURESETTING; +#define GET_PS_FEATURESETTING 4121 +#define FEATURESETTING_PSLEVEL 2 +int GetPSLevel(HDC hDC) { + int device_type = ::GetDeviceCaps(hDC, TECHNOLOGY); + if (device_type != DT_RASPRINTER) { + return 0; + } + FX_DWORD esc = GET_PS_FEATURESETTING; + if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL)) { + int param = FEATURESETTING_PSLEVEL; + if (ExtEscape(hDC, GET_PS_FEATURESETTING, sizeof(int), (char*)¶m, + sizeof(int), (char*)¶m) > 0) { + return param; + } + } + esc = POSTSCRIPT_IDENTIFY; + if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL) == 0) { + esc = POSTSCRIPT_DATA; if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL)) { - int param = FEATURESETTING_PSLEVEL; - if (ExtEscape(hDC, GET_PS_FEATURESETTING, sizeof(int), (char*)¶m, sizeof(int), (char*)¶m) > 0) { - return param; - } - } - esc = POSTSCRIPT_IDENTIFY; - if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL) == 0) { - esc = POSTSCRIPT_DATA; - if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL)) { - return 2; - } - return 0; - } - esc = PSIDENT_GDICENTRIC; - if (ExtEscape(hDC, POSTSCRIPT_IDENTIFY, sizeof(FX_DWORD), (char*)&esc, 0, NULL) <= 0) { - return 2; - } - esc = GET_PS_FEATURESETTING; - if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL)) { - int param = FEATURESETTING_PSLEVEL; - if (ExtEscape(hDC, GET_PS_FEATURESETTING, sizeof(int), (char*)¶m, sizeof(int), (char*)¶m) > 0) { - return param; - } + return 2; } + return 0; + } + esc = PSIDENT_GDICENTRIC; + if (ExtEscape(hDC, POSTSCRIPT_IDENTIFY, sizeof(FX_DWORD), (char*)&esc, 0, + NULL) <= 0) { return 2; + } + esc = GET_PS_FEATURESETTING; + if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL)) { + int param = FEATURESETTING_PSLEVEL; + if (ExtEscape(hDC, GET_PS_FEATURESETTING, sizeof(int), (char*)¶m, + sizeof(int), (char*)¶m) > 0) { + return param; + } + } + return 2; } int CFX_WindowsDevice::m_psLevel = 2; -CFX_WindowsDevice::CFX_WindowsDevice(HDC hDC, FX_BOOL bCmykOutput, FX_BOOL bForcePSOutput, int psLevel) -{ - m_bForcePSOutput = bForcePSOutput; - m_psLevel = psLevel; - if (bForcePSOutput) { - IFX_RenderDeviceDriver* pDriver = new CPSPrinterDriver; - ((CPSPrinterDriver*)pDriver)->Init(hDC, psLevel, bCmykOutput); - SetDeviceDriver(pDriver); - return; - } - SetDeviceDriver(CreateDriver(hDC, bCmykOutput)); +CFX_WindowsDevice::CFX_WindowsDevice(HDC hDC, + FX_BOOL bCmykOutput, + FX_BOOL bForcePSOutput, + int psLevel) { + m_bForcePSOutput = bForcePSOutput; + m_psLevel = psLevel; + if (bForcePSOutput) { + IFX_RenderDeviceDriver* pDriver = new CPSPrinterDriver; + ((CPSPrinterDriver*)pDriver)->Init(hDC, psLevel, bCmykOutput); + SetDeviceDriver(pDriver); + return; + } + SetDeviceDriver(CreateDriver(hDC, bCmykOutput)); } -HDC CFX_WindowsDevice::GetDC() const -{ - IFX_RenderDeviceDriver *pRDD = GetDeviceDriver(); - if (!pRDD) { - return NULL; - } - return (HDC)pRDD->GetPlatformSurface(); +HDC CFX_WindowsDevice::GetDC() const { + IFX_RenderDeviceDriver* pRDD = GetDeviceDriver(); + if (!pRDD) { + return NULL; + } + return (HDC)pRDD->GetPlatformSurface(); } -IFX_RenderDeviceDriver* CFX_WindowsDevice::CreateDriver(HDC hDC, FX_BOOL bCmykOutput) -{ - int device_type = ::GetDeviceCaps(hDC, TECHNOLOGY); - int obj_type = ::GetObjectType(hDC); - int device_class; - if (device_type == DT_RASPRINTER || device_type == DT_PLOTTER || obj_type == OBJ_ENHMETADC) { - device_class = FXDC_PRINTER; - } else { - device_class = FXDC_DISPLAY; - } - if (device_class == FXDC_PRINTER) { - return new CGdiPrinterDriver(hDC); - } - return new CGdiDisplayDriver(hDC); +IFX_RenderDeviceDriver* CFX_WindowsDevice::CreateDriver(HDC hDC, + FX_BOOL bCmykOutput) { + int device_type = ::GetDeviceCaps(hDC, TECHNOLOGY); + int obj_type = ::GetObjectType(hDC); + int device_class; + if (device_type == DT_RASPRINTER || device_type == DT_PLOTTER || + obj_type == OBJ_ENHMETADC) { + device_class = FXDC_PRINTER; + } else { + device_class = FXDC_DISPLAY; + } + if (device_class == FXDC_PRINTER) { + return new CGdiPrinterDriver(hDC); + } + return new CGdiDisplayDriver(hDC); } -CFX_WinBitmapDevice::CFX_WinBitmapDevice(int width, int height, FXDIB_Format format) -{ - BITMAPINFOHEADER bmih; - FXSYS_memset(&bmih, 0, sizeof (BITMAPINFOHEADER)); - bmih.biSize = sizeof(BITMAPINFOHEADER); - bmih.biBitCount = format & 0xff; - bmih.biHeight = -height; - bmih.biPlanes = 1; - bmih.biWidth = width; - uint8_t* pBuffer; - m_hBitmap = CreateDIBSection(NULL, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, (void**)&pBuffer, NULL, 0); - if (m_hBitmap == NULL) { - return; - } - CFX_DIBitmap* pBitmap = new CFX_DIBitmap; - pBitmap->Create(width, height, format, pBuffer); - SetBitmap(pBitmap); - m_hDC = ::CreateCompatibleDC(NULL); - m_hOldBitmap = (HBITMAP)SelectObject(m_hDC, m_hBitmap); - IFX_RenderDeviceDriver* pDriver = new CGdiDisplayDriver(m_hDC); - SetDeviceDriver(pDriver); +CFX_WinBitmapDevice::CFX_WinBitmapDevice(int width, + int height, + FXDIB_Format format) { + BITMAPINFOHEADER bmih; + FXSYS_memset(&bmih, 0, sizeof(BITMAPINFOHEADER)); + bmih.biSize = sizeof(BITMAPINFOHEADER); + bmih.biBitCount = format & 0xff; + bmih.biHeight = -height; + bmih.biPlanes = 1; + bmih.biWidth = width; + uint8_t* pBuffer; + m_hBitmap = CreateDIBSection(NULL, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, + (void**)&pBuffer, NULL, 0); + if (m_hBitmap == NULL) { + return; + } + CFX_DIBitmap* pBitmap = new CFX_DIBitmap; + pBitmap->Create(width, height, format, pBuffer); + SetBitmap(pBitmap); + m_hDC = ::CreateCompatibleDC(NULL); + m_hOldBitmap = (HBITMAP)SelectObject(m_hDC, m_hBitmap); + IFX_RenderDeviceDriver* pDriver = new CGdiDisplayDriver(m_hDC); + SetDeviceDriver(pDriver); } -CFX_WinBitmapDevice::~CFX_WinBitmapDevice() -{ - if (m_hDC) { - SelectObject(m_hDC, m_hOldBitmap); - DeleteDC(m_hDC); - } - if (m_hBitmap) { - DeleteObject(m_hBitmap); - } - delete GetBitmap(); +CFX_WinBitmapDevice::~CFX_WinBitmapDevice() { + if (m_hDC) { + SelectObject(m_hDC, m_hOldBitmap); + DeleteDC(m_hDC); + } + if (m_hBitmap) { + DeleteObject(m_hBitmap); + } + delete GetBitmap(); } #endif // _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_ diff --git a/core/src/fxge/win32/fx_win32_dib.cpp b/core/src/fxge/win32/fx_win32_dib.cpp index 3dcfce4802..b1ffe8080d 100644 --- a/core/src/fxge/win32/fx_win32_dib.cpp +++ b/core/src/fxge/win32/fx_win32_dib.cpp @@ -5,273 +5,282 @@ // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com #include "../../../include/fxge/fx_ge.h" -#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_DESKTOP_ +#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_DESKTOP_ #include #include "../../../include/fxge/fx_ge_win32.h" #include "win32_int.h" -CFX_ByteString CFX_WindowsDIB::GetBitmapInfo(const CFX_DIBitmap* pBitmap) -{ - CFX_ByteString result; - int len = sizeof (BITMAPINFOHEADER); - if (pBitmap->GetBPP() == 1 || pBitmap->GetBPP() == 8) { - len += sizeof (DWORD) * (int)(1 << pBitmap->GetBPP()); - } - BITMAPINFOHEADER* pbmih = (BITMAPINFOHEADER*)result.GetBuffer(len); - FXSYS_memset(pbmih, 0, sizeof (BITMAPINFOHEADER)); - pbmih->biSize = sizeof(BITMAPINFOHEADER); - pbmih->biBitCount = pBitmap->GetBPP(); - pbmih->biCompression = BI_RGB; - pbmih->biHeight = -(int)pBitmap->GetHeight(); - pbmih->biPlanes = 1; - pbmih->biWidth = pBitmap->GetWidth(); - if (pBitmap->GetBPP() == 8) { - FX_DWORD* pPalette = (FX_DWORD*)(pbmih + 1); - if (pBitmap->GetPalette() == NULL) { - for (int i = 0; i < 256; i ++) { - pPalette[i] = i * 0x010101; - } - } else { - for (int i = 0; i < 256; i ++) { - pPalette[i] = pBitmap->GetPalette()[i]; - } - } +CFX_ByteString CFX_WindowsDIB::GetBitmapInfo(const CFX_DIBitmap* pBitmap) { + CFX_ByteString result; + int len = sizeof(BITMAPINFOHEADER); + if (pBitmap->GetBPP() == 1 || pBitmap->GetBPP() == 8) { + len += sizeof(DWORD) * (int)(1 << pBitmap->GetBPP()); + } + BITMAPINFOHEADER* pbmih = (BITMAPINFOHEADER*)result.GetBuffer(len); + FXSYS_memset(pbmih, 0, sizeof(BITMAPINFOHEADER)); + pbmih->biSize = sizeof(BITMAPINFOHEADER); + pbmih->biBitCount = pBitmap->GetBPP(); + pbmih->biCompression = BI_RGB; + pbmih->biHeight = -(int)pBitmap->GetHeight(); + pbmih->biPlanes = 1; + pbmih->biWidth = pBitmap->GetWidth(); + if (pBitmap->GetBPP() == 8) { + FX_DWORD* pPalette = (FX_DWORD*)(pbmih + 1); + if (pBitmap->GetPalette() == NULL) { + for (int i = 0; i < 256; i++) { + pPalette[i] = i * 0x010101; + } + } else { + for (int i = 0; i < 256; i++) { + pPalette[i] = pBitmap->GetPalette()[i]; + } } - if (pBitmap->GetBPP() == 1) { - FX_DWORD* pPalette = (FX_DWORD*)(pbmih + 1); - if (pBitmap->GetPalette() == NULL) { - pPalette[0] = 0; - pPalette[1] = 0xffffff; - } else { - pPalette[0] = pBitmap->GetPalette()[0]; - pPalette[1] = pBitmap->GetPalette()[1]; - } + } + if (pBitmap->GetBPP() == 1) { + FX_DWORD* pPalette = (FX_DWORD*)(pbmih + 1); + if (pBitmap->GetPalette() == NULL) { + pPalette[0] = 0; + pPalette[1] = 0xffffff; + } else { + pPalette[0] = pBitmap->GetPalette()[0]; + pPalette[1] = pBitmap->GetPalette()[1]; } - result.ReleaseBuffer(len); - return result; + } + result.ReleaseBuffer(len); + return result; } -CFX_DIBitmap* _FX_WindowsDIB_LoadFromBuf(BITMAPINFO* pbmi, LPVOID pData, FX_BOOL bAlpha) -{ - int width = pbmi->bmiHeader.biWidth; - int height = pbmi->bmiHeader.biHeight; - BOOL bBottomUp = TRUE; - if (height < 0) { - height = -height; - bBottomUp = FALSE; - } - int pitch = (width * pbmi->bmiHeader.biBitCount + 31) / 32 * 4; - CFX_DIBitmap* pBitmap = new CFX_DIBitmap; - FXDIB_Format format = bAlpha ? (FXDIB_Format)(pbmi->bmiHeader.biBitCount + 0x200) : (FXDIB_Format)pbmi->bmiHeader.biBitCount; - FX_BOOL ret = pBitmap->Create(width, height, format); - if (!ret) { - delete pBitmap; - return NULL; +CFX_DIBitmap* _FX_WindowsDIB_LoadFromBuf(BITMAPINFO* pbmi, + LPVOID pData, + FX_BOOL bAlpha) { + int width = pbmi->bmiHeader.biWidth; + int height = pbmi->bmiHeader.biHeight; + BOOL bBottomUp = TRUE; + if (height < 0) { + height = -height; + bBottomUp = FALSE; + } + int pitch = (width * pbmi->bmiHeader.biBitCount + 31) / 32 * 4; + CFX_DIBitmap* pBitmap = new CFX_DIBitmap; + FXDIB_Format format = bAlpha + ? (FXDIB_Format)(pbmi->bmiHeader.biBitCount + 0x200) + : (FXDIB_Format)pbmi->bmiHeader.biBitCount; + FX_BOOL ret = pBitmap->Create(width, height, format); + if (!ret) { + delete pBitmap; + return NULL; + } + FXSYS_memcpy(pBitmap->GetBuffer(), pData, pitch * height); + if (bBottomUp) { + uint8_t* temp_buf = FX_Alloc(uint8_t, pitch); + int top = 0, bottom = height - 1; + while (top < bottom) { + FXSYS_memcpy(temp_buf, pBitmap->GetBuffer() + top * pitch, pitch); + FXSYS_memcpy(pBitmap->GetBuffer() + top * pitch, + pBitmap->GetBuffer() + bottom * pitch, pitch); + FXSYS_memcpy(pBitmap->GetBuffer() + bottom * pitch, temp_buf, pitch); + top++; + bottom--; } - FXSYS_memcpy(pBitmap->GetBuffer(), pData, pitch * height); - if (bBottomUp) { - uint8_t* temp_buf = FX_Alloc(uint8_t, pitch); - int top = 0, bottom = height - 1; - while (top < bottom) { - FXSYS_memcpy(temp_buf, pBitmap->GetBuffer() + top * pitch, pitch); - FXSYS_memcpy(pBitmap->GetBuffer() + top * pitch, pBitmap->GetBuffer() + bottom * pitch, pitch); - FXSYS_memcpy(pBitmap->GetBuffer() + bottom * pitch, temp_buf, pitch); - top ++; - bottom --; - } - FX_Free(temp_buf); - temp_buf = NULL; + FX_Free(temp_buf); + temp_buf = NULL; + } + if (pbmi->bmiHeader.biBitCount == 1) { + for (int i = 0; i < 2; i++) { + pBitmap->SetPaletteEntry(i, ((FX_DWORD*)pbmi->bmiColors)[i] | 0xff000000); } - if (pbmi->bmiHeader.biBitCount == 1) { - for (int i = 0; i < 2; i ++) { - pBitmap->SetPaletteEntry(i, ((FX_DWORD*)pbmi->bmiColors)[i] | 0xff000000); - } - } else if (pbmi->bmiHeader.biBitCount == 8) { - for (int i = 0; i < 256; i ++) { - pBitmap->SetPaletteEntry(i, ((FX_DWORD*)pbmi->bmiColors)[i] | 0xff000000); - } + } else if (pbmi->bmiHeader.biBitCount == 8) { + for (int i = 0; i < 256; i++) { + pBitmap->SetPaletteEntry(i, ((FX_DWORD*)pbmi->bmiColors)[i] | 0xff000000); } - return pBitmap; + } + return pBitmap; } -CFX_DIBitmap* CFX_WindowsDIB::LoadFromBuf(BITMAPINFO* pbmi, LPVOID pData) -{ - return _FX_WindowsDIB_LoadFromBuf(pbmi, pData, FALSE); +CFX_DIBitmap* CFX_WindowsDIB::LoadFromBuf(BITMAPINFO* pbmi, LPVOID pData) { + return _FX_WindowsDIB_LoadFromBuf(pbmi, pData, FALSE); } -HBITMAP CFX_WindowsDIB::GetDDBitmap(const CFX_DIBitmap* pBitmap, HDC hDC) -{ - CFX_ByteString info = GetBitmapInfo(pBitmap); - HBITMAP hBitmap = NULL; - hBitmap = CreateDIBitmap(hDC, (BITMAPINFOHEADER*)info.c_str(), CBM_INIT, - pBitmap->GetBuffer(), (BITMAPINFO*)info.c_str(), DIB_RGB_COLORS); - return hBitmap; +HBITMAP CFX_WindowsDIB::GetDDBitmap(const CFX_DIBitmap* pBitmap, HDC hDC) { + CFX_ByteString info = GetBitmapInfo(pBitmap); + HBITMAP hBitmap = NULL; + hBitmap = CreateDIBitmap(hDC, (BITMAPINFOHEADER*)info.c_str(), CBM_INIT, + pBitmap->GetBuffer(), (BITMAPINFO*)info.c_str(), + DIB_RGB_COLORS); + return hBitmap; } -void GetBitmapSize(HBITMAP hBitmap, int& w, int& h) -{ - BITMAP bmp; - GetObject(hBitmap, sizeof bmp, &bmp); - w = bmp.bmWidth; - h = bmp.bmHeight; +void GetBitmapSize(HBITMAP hBitmap, int& w, int& h) { + BITMAP bmp; + GetObject(hBitmap, sizeof bmp, &bmp); + w = bmp.bmWidth; + h = bmp.bmHeight; } -CFX_DIBitmap* CFX_WindowsDIB::LoadFromFile(const FX_WCHAR* filename) -{ - CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData(); - if (pPlatform->m_GdiplusExt.IsAvailable()) { - WINDIB_Open_Args_ args; - args.flags = WINDIB_OPEN_PATHNAME; - args.path_name = filename; - return pPlatform->m_GdiplusExt.LoadDIBitmap(args); - } - HBITMAP hBitmap = (HBITMAP)LoadImageW(NULL, (wchar_t*)filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); - if (hBitmap == NULL) { - return NULL; - } - HDC hDC = CreateCompatibleDC(NULL); - int width, height; - GetBitmapSize(hBitmap, width, height); - CFX_DIBitmap* pDIBitmap = new CFX_DIBitmap; - if (!pDIBitmap->Create(width, height, FXDIB_Rgb)) { - delete pDIBitmap; - DeleteDC(hDC); - return NULL; - } - CFX_ByteString info = GetBitmapInfo(pDIBitmap); - int ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAPINFO*)info.c_str(), DIB_RGB_COLORS); - if (!ret) { - delete pDIBitmap; - pDIBitmap = NULL; - } +CFX_DIBitmap* CFX_WindowsDIB::LoadFromFile(const FX_WCHAR* filename) { + CWin32Platform* pPlatform = + (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData(); + if (pPlatform->m_GdiplusExt.IsAvailable()) { + WINDIB_Open_Args_ args; + args.flags = WINDIB_OPEN_PATHNAME; + args.path_name = filename; + return pPlatform->m_GdiplusExt.LoadDIBitmap(args); + } + HBITMAP hBitmap = (HBITMAP)LoadImageW(NULL, (wchar_t*)filename, IMAGE_BITMAP, + 0, 0, LR_LOADFROMFILE); + if (hBitmap == NULL) { + return NULL; + } + HDC hDC = CreateCompatibleDC(NULL); + int width, height; + GetBitmapSize(hBitmap, width, height); + CFX_DIBitmap* pDIBitmap = new CFX_DIBitmap; + if (!pDIBitmap->Create(width, height, FXDIB_Rgb)) { + delete pDIBitmap; DeleteDC(hDC); - return pDIBitmap; + return NULL; + } + CFX_ByteString info = GetBitmapInfo(pDIBitmap); + int ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), + (BITMAPINFO*)info.c_str(), DIB_RGB_COLORS); + if (!ret) { + delete pDIBitmap; + pDIBitmap = NULL; + } + DeleteDC(hDC); + return pDIBitmap; } -CFX_DIBitmap* CFX_WindowsDIB::LoadDIBitmap(WINDIB_Open_Args_ args) -{ - CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData(); - if (pPlatform->m_GdiplusExt.IsAvailable()) { - return pPlatform->m_GdiplusExt.LoadDIBitmap(args); - } - if (args.flags == WINDIB_OPEN_MEMORY) { - return NULL; - } - HBITMAP hBitmap = (HBITMAP)LoadImageW(NULL, (wchar_t*)args.path_name, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); - if (hBitmap == NULL) { - return NULL; - } - HDC hDC = CreateCompatibleDC(NULL); - int width, height; - GetBitmapSize(hBitmap, width, height); - CFX_DIBitmap* pDIBitmap = new CFX_DIBitmap; - if (!pDIBitmap->Create(width, height, FXDIB_Rgb)) { - delete pDIBitmap; - DeleteDC(hDC); - return NULL; - } - CFX_ByteString info = GetBitmapInfo(pDIBitmap); - int ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAPINFO*)info.c_str(), DIB_RGB_COLORS); - if (!ret) { - delete pDIBitmap; - pDIBitmap = NULL; - } +CFX_DIBitmap* CFX_WindowsDIB::LoadDIBitmap(WINDIB_Open_Args_ args) { + CWin32Platform* pPlatform = + (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData(); + if (pPlatform->m_GdiplusExt.IsAvailable()) { + return pPlatform->m_GdiplusExt.LoadDIBitmap(args); + } + if (args.flags == WINDIB_OPEN_MEMORY) { + return NULL; + } + HBITMAP hBitmap = (HBITMAP)LoadImageW(NULL, (wchar_t*)args.path_name, + IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); + if (hBitmap == NULL) { + return NULL; + } + HDC hDC = CreateCompatibleDC(NULL); + int width, height; + GetBitmapSize(hBitmap, width, height); + CFX_DIBitmap* pDIBitmap = new CFX_DIBitmap; + if (!pDIBitmap->Create(width, height, FXDIB_Rgb)) { + delete pDIBitmap; DeleteDC(hDC); - return pDIBitmap; + return NULL; + } + CFX_ByteString info = GetBitmapInfo(pDIBitmap); + int ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), + (BITMAPINFO*)info.c_str(), DIB_RGB_COLORS); + if (!ret) { + delete pDIBitmap; + pDIBitmap = NULL; + } + DeleteDC(hDC); + return pDIBitmap; } -CFX_DIBitmap* CFX_WindowsDIB::LoadFromDDB(HDC hDC, HBITMAP hBitmap, FX_DWORD* pPalette, FX_DWORD palsize) -{ - FX_BOOL bCreatedDC = hDC == NULL; - if (hDC == NULL) { - hDC = CreateCompatibleDC(NULL); +CFX_DIBitmap* CFX_WindowsDIB::LoadFromDDB(HDC hDC, + HBITMAP hBitmap, + FX_DWORD* pPalette, + FX_DWORD palsize) { + FX_BOOL bCreatedDC = hDC == NULL; + if (hDC == NULL) { + hDC = CreateCompatibleDC(NULL); + } + BITMAPINFOHEADER bmih; + FXSYS_memset(&bmih, 0, sizeof bmih); + bmih.biSize = sizeof bmih; + GetDIBits(hDC, hBitmap, 0, 0, NULL, (BITMAPINFO*)&bmih, DIB_RGB_COLORS); + int width = bmih.biWidth; + int height = abs(bmih.biHeight); + bmih.biHeight = -height; + bmih.biCompression = BI_RGB; + CFX_DIBitmap* pDIBitmap = new CFX_DIBitmap; + int ret = 0; + if (bmih.biBitCount == 1 || bmih.biBitCount == 8) { + int size = sizeof(BITMAPINFOHEADER) + 8; + if (bmih.biBitCount == 8) { + size += sizeof(FX_DWORD) * 254; } - BITMAPINFOHEADER bmih; - FXSYS_memset(&bmih, 0, sizeof bmih); - bmih.biSize = sizeof bmih; - GetDIBits(hDC, hBitmap, 0, 0, NULL, (BITMAPINFO*)&bmih, DIB_RGB_COLORS); - int width = bmih.biWidth; - int height = abs(bmih.biHeight); - bmih.biHeight = -height; - bmih.biCompression = BI_RGB; - CFX_DIBitmap* pDIBitmap = new CFX_DIBitmap; - int ret = 0; - if (bmih.biBitCount == 1 || bmih.biBitCount == 8) { - int size = sizeof (BITMAPINFOHEADER) + 8; - if (bmih.biBitCount == 8) { - size += sizeof (FX_DWORD) * 254; - } - BITMAPINFO* pbmih = (BITMAPINFO*)FX_Alloc(uint8_t, size); - pbmih->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - pbmih->bmiHeader.biBitCount = bmih.biBitCount; - pbmih->bmiHeader.biCompression = BI_RGB; - pbmih->bmiHeader.biHeight = -height; - pbmih->bmiHeader.biPlanes = 1; - pbmih->bmiHeader.biWidth = bmih.biWidth; - if (!pDIBitmap->Create(bmih.biWidth, height, bmih.biBitCount == 1 ? FXDIB_1bppRgb : FXDIB_8bppRgb)) { - delete pDIBitmap; - FX_Free(pbmih); - if (bCreatedDC) { - DeleteDC(hDC); - } - return NULL; - } - ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAPINFO*)pbmih, DIB_RGB_COLORS); - FX_Free(pbmih); - pbmih = NULL; - pDIBitmap->CopyPalette(pPalette, palsize); - } else { - if (bmih.biBitCount <= 24) { - bmih.biBitCount = 24; - } else { - bmih.biBitCount = 32; - } - if (!pDIBitmap->Create(bmih.biWidth, height, bmih.biBitCount == 24 ? FXDIB_Rgb : FXDIB_Rgb32)) { - delete pDIBitmap; - if (bCreatedDC) { - DeleteDC(hDC); - } - return NULL; - } - ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAPINFO*)&bmih, DIB_RGB_COLORS); - if (ret != 0 && bmih.biBitCount == 32) { - int pitch = pDIBitmap->GetPitch(); - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = (uint8_t*)(pDIBitmap->GetBuffer() + row * pitch); - for (int col = 0; col < width; col++) { - dest_scan[3] = 255; - dest_scan += 4; - } - } - } + BITMAPINFO* pbmih = (BITMAPINFO*)FX_Alloc(uint8_t, size); + pbmih->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + pbmih->bmiHeader.biBitCount = bmih.biBitCount; + pbmih->bmiHeader.biCompression = BI_RGB; + pbmih->bmiHeader.biHeight = -height; + pbmih->bmiHeader.biPlanes = 1; + pbmih->bmiHeader.biWidth = bmih.biWidth; + if (!pDIBitmap->Create(bmih.biWidth, height, bmih.biBitCount == 1 + ? FXDIB_1bppRgb + : FXDIB_8bppRgb)) { + delete pDIBitmap; + FX_Free(pbmih); + if (bCreatedDC) { + DeleteDC(hDC); + } + return NULL; } - if (ret == 0) { - delete pDIBitmap; - pDIBitmap = NULL; + ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), + (BITMAPINFO*)pbmih, DIB_RGB_COLORS); + FX_Free(pbmih); + pbmih = NULL; + pDIBitmap->CopyPalette(pPalette, palsize); + } else { + if (bmih.biBitCount <= 24) { + bmih.biBitCount = 24; + } else { + bmih.biBitCount = 32; } - if (bCreatedDC) { + if (!pDIBitmap->Create(bmih.biWidth, height, + bmih.biBitCount == 24 ? FXDIB_Rgb : FXDIB_Rgb32)) { + delete pDIBitmap; + if (bCreatedDC) { DeleteDC(hDC); + } + return NULL; } - return pDIBitmap; + ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), + (BITMAPINFO*)&bmih, DIB_RGB_COLORS); + if (ret != 0 && bmih.biBitCount == 32) { + int pitch = pDIBitmap->GetPitch(); + for (int row = 0; row < height; row++) { + uint8_t* dest_scan = (uint8_t*)(pDIBitmap->GetBuffer() + row * pitch); + for (int col = 0; col < width; col++) { + dest_scan[3] = 255; + dest_scan += 4; + } + } + } + } + if (ret == 0) { + delete pDIBitmap; + pDIBitmap = NULL; + } + if (bCreatedDC) { + DeleteDC(hDC); + } + return pDIBitmap; } -CFX_WindowsDIB::CFX_WindowsDIB(HDC hDC, int width, int height) -{ - Create(width, height, FXDIB_Rgb, (uint8_t*)1); - BITMAPINFOHEADER bmih; - FXSYS_memset(&bmih, 0, sizeof bmih); - bmih.biSize = sizeof bmih; - bmih.biBitCount = 24; - bmih.biHeight = -height; - bmih.biPlanes = 1; - bmih.biWidth = width; - m_hBitmap = CreateDIBSection(hDC, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, (LPVOID*)&m_pBuffer, NULL, 0); - m_hMemDC = CreateCompatibleDC(hDC); - m_hOldBitmap = (HBITMAP)SelectObject(m_hMemDC, m_hBitmap); +CFX_WindowsDIB::CFX_WindowsDIB(HDC hDC, int width, int height) { + Create(width, height, FXDIB_Rgb, (uint8_t*)1); + BITMAPINFOHEADER bmih; + FXSYS_memset(&bmih, 0, sizeof bmih); + bmih.biSize = sizeof bmih; + bmih.biBitCount = 24; + bmih.biHeight = -height; + bmih.biPlanes = 1; + bmih.biWidth = width; + m_hBitmap = CreateDIBSection(hDC, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, + (LPVOID*)&m_pBuffer, NULL, 0); + m_hMemDC = CreateCompatibleDC(hDC); + m_hOldBitmap = (HBITMAP)SelectObject(m_hMemDC, m_hBitmap); } -CFX_WindowsDIB::~CFX_WindowsDIB() -{ - SelectObject(m_hMemDC, m_hOldBitmap); - DeleteDC(m_hMemDC); - DeleteObject(m_hBitmap); +CFX_WindowsDIB::~CFX_WindowsDIB() { + SelectObject(m_hMemDC, m_hOldBitmap); + DeleteDC(m_hMemDC); + DeleteObject(m_hBitmap); } -void CFX_WindowsDIB::LoadFromDevice(HDC hDC, int left, int top) -{ - ::BitBlt(m_hMemDC, 0, 0, m_Width, m_Height, hDC, left, top, SRCCOPY); +void CFX_WindowsDIB::LoadFromDevice(HDC hDC, int left, int top) { + ::BitBlt(m_hMemDC, 0, 0, m_Width, m_Height, hDC, left, top, SRCCOPY); } -void CFX_WindowsDIB::SetToDevice(HDC hDC, int left, int top) -{ - ::BitBlt(hDC, left, top, m_Width, m_Height, m_hMemDC, 0, 0, SRCCOPY); +void CFX_WindowsDIB::SetToDevice(HDC hDC, int left, int top) { + ::BitBlt(hDC, left, top, m_Width, m_Height, m_hMemDC, 0, 0, SRCCOPY); } #endif diff --git a/core/src/fxge/win32/fx_win32_dwrite.cpp b/core/src/fxge/win32/fx_win32_dwrite.cpp index 65a35d86a1..5a3c16c2af 100644 --- a/core/src/fxge/win32/fx_win32_dwrite.cpp +++ b/core/src/fxge/win32/fx_win32_dwrite.cpp @@ -9,396 +9,362 @@ #include "../../../include/fxge/fx_ge_win32.h" #include "dwrite_int.h" #include -typedef HRESULT (__stdcall *FuncType_DWriteCreateFactory)(__in DWRITE_FACTORY_TYPE, __in REFIID, __out IUnknown **); +typedef HRESULT(__stdcall* FuncType_DWriteCreateFactory)( + __in DWRITE_FACTORY_TYPE, + __in REFIID, + __out IUnknown**); template -inline void SafeRelease(InterfaceType** currentObject) -{ - if (*currentObject != NULL) { - (*currentObject)->Release(); - *currentObject = NULL; - } +inline void SafeRelease(InterfaceType** currentObject) { + if (*currentObject != NULL) { + (*currentObject)->Release(); + *currentObject = NULL; + } } template -inline InterfaceType* SafeAcquire(InterfaceType* newObject) -{ - if (newObject != NULL) { - newObject->AddRef(); - } - return newObject; +inline InterfaceType* SafeAcquire(InterfaceType* newObject) { + if (newObject != NULL) { + newObject->AddRef(); + } + return newObject; } -class CDwFontFileStream final : public IDWriteFontFileStream -{ -public: - explicit CDwFontFileStream(void const* fontFileReferenceKey, UINT32 fontFileReferenceKeySize); - virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject); - virtual ULONG STDMETHODCALLTYPE AddRef(); - virtual ULONG STDMETHODCALLTYPE Release(); - virtual HRESULT STDMETHODCALLTYPE ReadFileFragment(void const** fragmentStart, UINT64 fileOffset, UINT64 fragmentSize, OUT void** fragmentContext); - virtual void STDMETHODCALLTYPE ReleaseFileFragment(void* fragmentContext); - virtual HRESULT STDMETHODCALLTYPE GetFileSize(OUT UINT64* fileSize); - virtual HRESULT STDMETHODCALLTYPE GetLastWriteTime(OUT UINT64* lastWriteTime); - bool IsInitialized() - { - return resourcePtr_ != NULL; - } -private: - ULONG refCount_; - void const* resourcePtr_; - DWORD resourceSize_; +class CDwFontFileStream final : public IDWriteFontFileStream { + public: + explicit CDwFontFileStream(void const* fontFileReferenceKey, + UINT32 fontFileReferenceKeySize); + virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, + void** ppvObject); + virtual ULONG STDMETHODCALLTYPE AddRef(); + virtual ULONG STDMETHODCALLTYPE Release(); + virtual HRESULT STDMETHODCALLTYPE + ReadFileFragment(void const** fragmentStart, + UINT64 fileOffset, + UINT64 fragmentSize, + OUT void** fragmentContext); + virtual void STDMETHODCALLTYPE ReleaseFileFragment(void* fragmentContext); + virtual HRESULT STDMETHODCALLTYPE GetFileSize(OUT UINT64* fileSize); + virtual HRESULT STDMETHODCALLTYPE GetLastWriteTime(OUT UINT64* lastWriteTime); + bool IsInitialized() { return resourcePtr_ != NULL; } + + private: + ULONG refCount_; + void const* resourcePtr_; + DWORD resourceSize_; }; -class CDwFontFileLoader final : public IDWriteFontFileLoader -{ -public: - virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject); - virtual ULONG STDMETHODCALLTYPE AddRef(); - virtual ULONG STDMETHODCALLTYPE Release(); - virtual HRESULT STDMETHODCALLTYPE CreateStreamFromKey(void const* fontFileReferenceKey, UINT32 fontFileReferenceKeySize, OUT IDWriteFontFileStream** fontFileStream); +class CDwFontFileLoader final : public IDWriteFontFileLoader { + public: + virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, + void** ppvObject); + virtual ULONG STDMETHODCALLTYPE AddRef(); + virtual ULONG STDMETHODCALLTYPE Release(); + virtual HRESULT STDMETHODCALLTYPE + CreateStreamFromKey(void const* fontFileReferenceKey, + UINT32 fontFileReferenceKeySize, + OUT IDWriteFontFileStream** fontFileStream); - static IDWriteFontFileLoader* GetLoader() - { - if (instance_ == NULL) { - instance_ = new CDwFontFileLoader(); - } - return instance_; + static IDWriteFontFileLoader* GetLoader() { + if (instance_ == NULL) { + instance_ = new CDwFontFileLoader(); } - static bool IsLoaderInitialized() - { - return instance_ != NULL; - } -private: - CDwFontFileLoader(); - ULONG refCount_; - static IDWriteFontFileLoader* instance_; + return instance_; + } + static bool IsLoaderInitialized() { return instance_ != NULL; } + + private: + CDwFontFileLoader(); + ULONG refCount_; + static IDWriteFontFileLoader* instance_; }; -class CDwFontContext -{ -public: - CDwFontContext(IDWriteFactory* dwriteFactory); - ~CDwFontContext(); - HRESULT Initialize(); -private: - CDwFontContext(CDwFontContext const&); - void operator=(CDwFontContext const&); - HRESULT hr_; - IDWriteFactory* dwriteFactory_; +class CDwFontContext { + public: + CDwFontContext(IDWriteFactory* dwriteFactory); + ~CDwFontContext(); + HRESULT Initialize(); + + private: + CDwFontContext(CDwFontContext const&); + void operator=(CDwFontContext const&); + HRESULT hr_; + IDWriteFactory* dwriteFactory_; }; -class CDwGdiTextRenderer -{ -public: - CDwGdiTextRenderer( - CFX_DIBitmap* pBitmap, - IDWriteBitmapRenderTarget* bitmapRenderTarget, - IDWriteRenderingParams* renderingParams - ); - ~CDwGdiTextRenderer(); - HRESULT STDMETHODCALLTYPE DrawGlyphRun( - const FX_RECT& text_bbox, - __in_opt CFX_ClipRgn* pClipRgn, - __in_opt DWRITE_MATRIX const* pMatrix, - FLOAT baselineOriginX, - FLOAT baselineOriginY, - DWRITE_MEASURING_MODE measuringMode, - __in DWRITE_GLYPH_RUN const* glyphRun, - const COLORREF& textColor - ); -private: - CFX_DIBitmap* pBitmap_; - IDWriteBitmapRenderTarget* pRenderTarget_; - IDWriteRenderingParams* pRenderingParams_; +class CDwGdiTextRenderer { + public: + CDwGdiTextRenderer(CFX_DIBitmap* pBitmap, + IDWriteBitmapRenderTarget* bitmapRenderTarget, + IDWriteRenderingParams* renderingParams); + ~CDwGdiTextRenderer(); + HRESULT STDMETHODCALLTYPE DrawGlyphRun(const FX_RECT& text_bbox, + __in_opt CFX_ClipRgn* pClipRgn, + __in_opt DWRITE_MATRIX const* pMatrix, + FLOAT baselineOriginX, + FLOAT baselineOriginY, + DWRITE_MEASURING_MODE measuringMode, + __in DWRITE_GLYPH_RUN const* glyphRun, + const COLORREF& textColor); + + private: + CFX_DIBitmap* pBitmap_; + IDWriteBitmapRenderTarget* pRenderTarget_; + IDWriteRenderingParams* pRenderingParams_; }; -CDWriteExt::CDWriteExt() -{ - m_hModule = NULL; - m_pDWriteFactory = NULL; - m_pDwFontContext = NULL; - m_pDwTextRenderer = NULL; +CDWriteExt::CDWriteExt() { + m_hModule = NULL; + m_pDWriteFactory = NULL; + m_pDwFontContext = NULL; + m_pDwTextRenderer = NULL; } -void CDWriteExt::Load() -{ -} -void CDWriteExt::Unload() -{ - if (m_pDwFontContext) { - delete (CDwFontContext*)m_pDwFontContext; - m_pDwFontContext = NULL; - } - SafeRelease((IDWriteFactory**)&m_pDWriteFactory); +void CDWriteExt::Load() {} +void CDWriteExt::Unload() { + if (m_pDwFontContext) { + delete (CDwFontContext*)m_pDwFontContext; + m_pDwFontContext = NULL; + } + SafeRelease((IDWriteFactory**)&m_pDWriteFactory); } -CDWriteExt::~CDWriteExt() -{ - Unload(); +CDWriteExt::~CDWriteExt() { + Unload(); } -LPVOID CDWriteExt::DwCreateFontFaceFromStream(uint8_t* pData, FX_DWORD size, int simulation_style) -{ - IDWriteFactory* pDwFactory = (IDWriteFactory*)m_pDWriteFactory; - IDWriteFontFile* pDwFontFile = NULL; - IDWriteFontFace* pDwFontFace = NULL; - BOOL isSupportedFontType = FALSE; - DWRITE_FONT_FILE_TYPE fontFileType; - DWRITE_FONT_FACE_TYPE fontFaceType; - UINT32 numberOfFaces; - DWRITE_FONT_SIMULATIONS fontStyle = (DWRITE_FONT_SIMULATIONS)(simulation_style & 3); - HRESULT hr = S_OK; - hr = pDwFactory->CreateCustomFontFileReference( - (void const*)pData, - (UINT32)size, - CDwFontFileLoader::GetLoader(), - &pDwFontFile - ); - if (FAILED(hr)) { - goto failed; - } - hr = pDwFontFile->Analyze( - &isSupportedFontType, - &fontFileType, - &fontFaceType, - &numberOfFaces - ); - if (FAILED(hr) || !isSupportedFontType || fontFaceType == DWRITE_FONT_FACE_TYPE_UNKNOWN) { - goto failed; - } - hr = pDwFactory->CreateFontFace( - fontFaceType, - 1, - &pDwFontFile, - 0, - fontStyle, - &pDwFontFace - ); - if (FAILED(hr)) { - goto failed; - } - SafeRelease(&pDwFontFile); - return pDwFontFace; +LPVOID CDWriteExt::DwCreateFontFaceFromStream(uint8_t* pData, + FX_DWORD size, + int simulation_style) { + IDWriteFactory* pDwFactory = (IDWriteFactory*)m_pDWriteFactory; + IDWriteFontFile* pDwFontFile = NULL; + IDWriteFontFace* pDwFontFace = NULL; + BOOL isSupportedFontType = FALSE; + DWRITE_FONT_FILE_TYPE fontFileType; + DWRITE_FONT_FACE_TYPE fontFaceType; + UINT32 numberOfFaces; + DWRITE_FONT_SIMULATIONS fontStyle = + (DWRITE_FONT_SIMULATIONS)(simulation_style & 3); + HRESULT hr = S_OK; + hr = pDwFactory->CreateCustomFontFileReference( + (void const*)pData, (UINT32)size, CDwFontFileLoader::GetLoader(), + &pDwFontFile); + if (FAILED(hr)) { + goto failed; + } + hr = pDwFontFile->Analyze(&isSupportedFontType, &fontFileType, &fontFaceType, + &numberOfFaces); + if (FAILED(hr) || !isSupportedFontType || + fontFaceType == DWRITE_FONT_FACE_TYPE_UNKNOWN) { + goto failed; + } + hr = pDwFactory->CreateFontFace(fontFaceType, 1, &pDwFontFile, 0, fontStyle, + &pDwFontFace); + if (FAILED(hr)) { + goto failed; + } + SafeRelease(&pDwFontFile); + return pDwFontFace; failed: - SafeRelease(&pDwFontFile); - return NULL; + SafeRelease(&pDwFontFile); + return NULL; } -FX_BOOL CDWriteExt::DwCreateRenderingTarget(CFX_DIBitmap* pBitmap, void** renderTarget) -{ - if (pBitmap->GetFormat() > FXDIB_Argb) { - return FALSE; - } - IDWriteFactory* pDwFactory = (IDWriteFactory*)m_pDWriteFactory; - IDWriteGdiInterop* pGdiInterop = NULL; - IDWriteBitmapRenderTarget* pBitmapRenderTarget = NULL; - IDWriteRenderingParams* pRenderingParams = NULL; - HRESULT hr = S_OK; - hr = pDwFactory->GetGdiInterop(&pGdiInterop); - if (FAILED(hr)) { - goto failed; - } - hr = pGdiInterop->CreateBitmapRenderTarget(NULL, pBitmap->GetWidth(), pBitmap->GetHeight(), - &pBitmapRenderTarget); - if (FAILED(hr)) { - goto failed; - } - hr = pDwFactory->CreateCustomRenderingParams( - 1.0f, - 0.0f, - 1.0f, - DWRITE_PIXEL_GEOMETRY_RGB, - DWRITE_RENDERING_MODE_DEFAULT, - &pRenderingParams - ); - if (FAILED(hr)) { - goto failed; - } - hr = pBitmapRenderTarget->SetPixelsPerDip(1.0f); - if (FAILED(hr)) { - goto failed; - } - *(CDwGdiTextRenderer**)renderTarget = new CDwGdiTextRenderer(pBitmap, pBitmapRenderTarget, pRenderingParams); - SafeRelease(&pGdiInterop); - SafeRelease(&pBitmapRenderTarget); - SafeRelease(&pRenderingParams); - return TRUE; -failed: - SafeRelease(&pGdiInterop); - SafeRelease(&pBitmapRenderTarget); - SafeRelease(&pRenderingParams); +FX_BOOL CDWriteExt::DwCreateRenderingTarget(CFX_DIBitmap* pBitmap, + void** renderTarget) { + if (pBitmap->GetFormat() > FXDIB_Argb) { return FALSE; + } + IDWriteFactory* pDwFactory = (IDWriteFactory*)m_pDWriteFactory; + IDWriteGdiInterop* pGdiInterop = NULL; + IDWriteBitmapRenderTarget* pBitmapRenderTarget = NULL; + IDWriteRenderingParams* pRenderingParams = NULL; + HRESULT hr = S_OK; + hr = pDwFactory->GetGdiInterop(&pGdiInterop); + if (FAILED(hr)) { + goto failed; + } + hr = pGdiInterop->CreateBitmapRenderTarget( + NULL, pBitmap->GetWidth(), pBitmap->GetHeight(), &pBitmapRenderTarget); + if (FAILED(hr)) { + goto failed; + } + hr = pDwFactory->CreateCustomRenderingParams( + 1.0f, 0.0f, 1.0f, DWRITE_PIXEL_GEOMETRY_RGB, + DWRITE_RENDERING_MODE_DEFAULT, &pRenderingParams); + if (FAILED(hr)) { + goto failed; + } + hr = pBitmapRenderTarget->SetPixelsPerDip(1.0f); + if (FAILED(hr)) { + goto failed; + } + *(CDwGdiTextRenderer**)renderTarget = + new CDwGdiTextRenderer(pBitmap, pBitmapRenderTarget, pRenderingParams); + SafeRelease(&pGdiInterop); + SafeRelease(&pBitmapRenderTarget); + SafeRelease(&pRenderingParams); + return TRUE; +failed: + SafeRelease(&pGdiInterop); + SafeRelease(&pBitmapRenderTarget); + SafeRelease(&pRenderingParams); + return FALSE; } -FX_BOOL CDWriteExt::DwRendingString(void* renderTarget, CFX_ClipRgn* pClipRgn, FX_RECT& stringRect, CFX_AffineMatrix* pMatrix, - void *font, FX_FLOAT font_size, FX_ARGB text_color, - int glyph_count, unsigned short* glyph_indices, - FX_FLOAT baselineOriginX, FX_FLOAT baselineOriginY, +FX_BOOL CDWriteExt::DwRendingString(void* renderTarget, + CFX_ClipRgn* pClipRgn, + FX_RECT& stringRect, + CFX_AffineMatrix* pMatrix, + void* font, + FX_FLOAT font_size, + FX_ARGB text_color, + int glyph_count, + unsigned short* glyph_indices, + FX_FLOAT baselineOriginX, + FX_FLOAT baselineOriginY, void* glyph_offsets, - FX_FLOAT* glyph_advances) -{ - if (renderTarget == NULL) { - return TRUE; - } - CDwGdiTextRenderer* pTextRenderer = (CDwGdiTextRenderer*)renderTarget; - DWRITE_MATRIX transform; - DWRITE_GLYPH_RUN glyphRun; - HRESULT hr = S_OK; - if (pMatrix) { - transform.m11 = pMatrix->a; - transform.m12 = pMatrix->b; - transform.m21 = pMatrix->c; - transform.m22 = pMatrix->d; - transform.dx = pMatrix->e; - transform.dy = pMatrix->f; - } - glyphRun.fontFace = (IDWriteFontFace*)font; - glyphRun.fontEmSize = font_size; - glyphRun.glyphCount = glyph_count; - glyphRun.glyphIndices = glyph_indices; - glyphRun.glyphAdvances = glyph_advances; - glyphRun.glyphOffsets = (DWRITE_GLYPH_OFFSET*)glyph_offsets; - glyphRun.isSideways = FALSE; - glyphRun.bidiLevel = 0; - hr = pTextRenderer->DrawGlyphRun( - stringRect, - pClipRgn, - pMatrix ? &transform : NULL, - baselineOriginX, baselineOriginY, - DWRITE_MEASURING_MODE_NATURAL, - &glyphRun, - RGB(FXARGB_R(text_color), FXARGB_G(text_color), FXARGB_B(text_color)) - ); - return SUCCEEDED(hr) ? TRUE : FALSE; + FX_FLOAT* glyph_advances) { + if (renderTarget == NULL) { + return TRUE; + } + CDwGdiTextRenderer* pTextRenderer = (CDwGdiTextRenderer*)renderTarget; + DWRITE_MATRIX transform; + DWRITE_GLYPH_RUN glyphRun; + HRESULT hr = S_OK; + if (pMatrix) { + transform.m11 = pMatrix->a; + transform.m12 = pMatrix->b; + transform.m21 = pMatrix->c; + transform.m22 = pMatrix->d; + transform.dx = pMatrix->e; + transform.dy = pMatrix->f; + } + glyphRun.fontFace = (IDWriteFontFace*)font; + glyphRun.fontEmSize = font_size; + glyphRun.glyphCount = glyph_count; + glyphRun.glyphIndices = glyph_indices; + glyphRun.glyphAdvances = glyph_advances; + glyphRun.glyphOffsets = (DWRITE_GLYPH_OFFSET*)glyph_offsets; + glyphRun.isSideways = FALSE; + glyphRun.bidiLevel = 0; + hr = pTextRenderer->DrawGlyphRun( + stringRect, pClipRgn, pMatrix ? &transform : NULL, baselineOriginX, + baselineOriginY, DWRITE_MEASURING_MODE_NATURAL, &glyphRun, + RGB(FXARGB_R(text_color), FXARGB_G(text_color), FXARGB_B(text_color))); + return SUCCEEDED(hr) ? TRUE : FALSE; } -void CDWriteExt::DwDeleteRenderingTarget(void* renderTarget) -{ - delete (CDwGdiTextRenderer*)renderTarget; +void CDWriteExt::DwDeleteRenderingTarget(void* renderTarget) { + delete (CDwGdiTextRenderer*)renderTarget; } -void CDWriteExt::DwDeleteFont(void* pFont) -{ - if (pFont) { - SafeRelease((IDWriteFontFace**)&pFont); - } +void CDWriteExt::DwDeleteFont(void* pFont) { + if (pFont) { + SafeRelease((IDWriteFontFace**)&pFont); + } } -CDwFontFileStream::CDwFontFileStream(void const* fontFileReferenceKey, UINT32 fontFileReferenceKeySize) -{ - refCount_ = 0; - resourcePtr_ = fontFileReferenceKey; - resourceSize_ = fontFileReferenceKeySize; +CDwFontFileStream::CDwFontFileStream(void const* fontFileReferenceKey, + UINT32 fontFileReferenceKeySize) { + refCount_ = 0; + resourcePtr_ = fontFileReferenceKey; + resourceSize_ = fontFileReferenceKeySize; } -HRESULT STDMETHODCALLTYPE CDwFontFileStream::QueryInterface(REFIID iid, void** ppvObject) -{ - if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileStream)) { - *ppvObject = this; - AddRef(); - return S_OK; - } - *ppvObject = NULL; - return E_NOINTERFACE; +HRESULT STDMETHODCALLTYPE CDwFontFileStream::QueryInterface(REFIID iid, + void** ppvObject) { + if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileStream)) { + *ppvObject = this; + AddRef(); + return S_OK; + } + *ppvObject = NULL; + return E_NOINTERFACE; } -ULONG STDMETHODCALLTYPE CDwFontFileStream::AddRef() -{ - return InterlockedIncrement((long*)(&refCount_)); +ULONG STDMETHODCALLTYPE CDwFontFileStream::AddRef() { + return InterlockedIncrement((long*)(&refCount_)); } -ULONG STDMETHODCALLTYPE CDwFontFileStream::Release() -{ - ULONG newCount = InterlockedDecrement((long*)(&refCount_)); - if (newCount == 0) { - delete this; - } - return newCount; +ULONG STDMETHODCALLTYPE CDwFontFileStream::Release() { + ULONG newCount = InterlockedDecrement((long*)(&refCount_)); + if (newCount == 0) { + delete this; + } + return newCount; } -HRESULT STDMETHODCALLTYPE CDwFontFileStream::ReadFileFragment( - void const** fragmentStart, - UINT64 fileOffset, - UINT64 fragmentSize, - OUT void** fragmentContext -) -{ - if (fileOffset <= resourceSize_ && fragmentSize <= resourceSize_ - fileOffset) { - *fragmentStart = static_cast(resourcePtr_) + static_cast(fileOffset); - *fragmentContext = NULL; - return S_OK; - } - *fragmentStart = NULL; +HRESULT STDMETHODCALLTYPE +CDwFontFileStream::ReadFileFragment(void const** fragmentStart, + UINT64 fileOffset, + UINT64 fragmentSize, + OUT void** fragmentContext) { + if (fileOffset <= resourceSize_ && + fragmentSize <= resourceSize_ - fileOffset) { + *fragmentStart = static_cast(resourcePtr_) + + static_cast(fileOffset); *fragmentContext = NULL; - return E_FAIL; -} -void STDMETHODCALLTYPE CDwFontFileStream::ReleaseFileFragment(void* fragmentContext) -{ -} -HRESULT STDMETHODCALLTYPE CDwFontFileStream::GetFileSize(OUT UINT64* fileSize) -{ - *fileSize = resourceSize_; return S_OK; + } + *fragmentStart = NULL; + *fragmentContext = NULL; + return E_FAIL; } -HRESULT STDMETHODCALLTYPE CDwFontFileStream::GetLastWriteTime(OUT UINT64* lastWriteTime) -{ - *lastWriteTime = 0; - return E_NOTIMPL; +void STDMETHODCALLTYPE +CDwFontFileStream::ReleaseFileFragment(void* fragmentContext) {} +HRESULT STDMETHODCALLTYPE CDwFontFileStream::GetFileSize(OUT UINT64* fileSize) { + *fileSize = resourceSize_; + return S_OK; +} +HRESULT STDMETHODCALLTYPE +CDwFontFileStream::GetLastWriteTime(OUT UINT64* lastWriteTime) { + *lastWriteTime = 0; + return E_NOTIMPL; } IDWriteFontFileLoader* CDwFontFileLoader::instance_ = NULL; -CDwFontFileLoader::CDwFontFileLoader() : - refCount_(0) -{ +CDwFontFileLoader::CDwFontFileLoader() : refCount_(0) {} +HRESULT STDMETHODCALLTYPE CDwFontFileLoader::QueryInterface(REFIID iid, + void** ppvObject) { + if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileLoader)) { + *ppvObject = this; + AddRef(); + return S_OK; + } + *ppvObject = NULL; + return E_NOINTERFACE; } -HRESULT STDMETHODCALLTYPE CDwFontFileLoader::QueryInterface(REFIID iid, void** ppvObject) -{ - if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileLoader)) { - *ppvObject = this; - AddRef(); - return S_OK; - } - *ppvObject = NULL; - return E_NOINTERFACE; +ULONG STDMETHODCALLTYPE CDwFontFileLoader::AddRef() { + return InterlockedIncrement((long*)(&refCount_)); } -ULONG STDMETHODCALLTYPE CDwFontFileLoader::AddRef() -{ - return InterlockedIncrement((long*)(&refCount_)); -} -ULONG STDMETHODCALLTYPE CDwFontFileLoader::Release() -{ - ULONG newCount = InterlockedDecrement((long*)(&refCount_)); - if (newCount == 0) { - instance_ = NULL; - delete this; - } - return newCount; +ULONG STDMETHODCALLTYPE CDwFontFileLoader::Release() { + ULONG newCount = InterlockedDecrement((long*)(&refCount_)); + if (newCount == 0) { + instance_ = NULL; + delete this; + } + return newCount; } HRESULT STDMETHODCALLTYPE CDwFontFileLoader::CreateStreamFromKey( void const* fontFileReferenceKey, UINT32 fontFileReferenceKeySize, - OUT IDWriteFontFileStream** fontFileStream -) -{ - *fontFileStream = NULL; - CDwFontFileStream* stream = new CDwFontFileStream(fontFileReferenceKey, fontFileReferenceKeySize); - if (!stream->IsInitialized()) { - delete stream; - return E_FAIL; - } - *fontFileStream = SafeAcquire(stream); - return S_OK; -} -CDwFontContext::CDwFontContext(IDWriteFactory* dwriteFactory) : - hr_(S_FALSE), - dwriteFactory_(SafeAcquire(dwriteFactory)) -{ -} -CDwFontContext::~CDwFontContext() -{ - if(dwriteFactory_ && hr_ == S_OK) { - dwriteFactory_->UnregisterFontFileLoader(CDwFontFileLoader::GetLoader()); - } - SafeRelease(&dwriteFactory_); + OUT IDWriteFontFileStream** fontFileStream) { + *fontFileStream = NULL; + CDwFontFileStream* stream = + new CDwFontFileStream(fontFileReferenceKey, fontFileReferenceKeySize); + if (!stream->IsInitialized()) { + delete stream; + return E_FAIL; + } + *fontFileStream = SafeAcquire(stream); + return S_OK; } -HRESULT CDwFontContext::Initialize() -{ - if (hr_ == S_FALSE) { - return hr_ = dwriteFactory_->RegisterFontFileLoader(CDwFontFileLoader::GetLoader()); - } - return hr_; +CDwFontContext::CDwFontContext(IDWriteFactory* dwriteFactory) + : hr_(S_FALSE), dwriteFactory_(SafeAcquire(dwriteFactory)) {} +CDwFontContext::~CDwFontContext() { + if (dwriteFactory_ && hr_ == S_OK) { + dwriteFactory_->UnregisterFontFileLoader(CDwFontFileLoader::GetLoader()); + } + SafeRelease(&dwriteFactory_); } -CDwGdiTextRenderer::CDwGdiTextRenderer(CFX_DIBitmap* pBitmap, IDWriteBitmapRenderTarget* bitmapRenderTarget, IDWriteRenderingParams* renderingParams): - pBitmap_(pBitmap), - pRenderTarget_(SafeAcquire(bitmapRenderTarget)), - pRenderingParams_(SafeAcquire(renderingParams)) -{ +HRESULT CDwFontContext::Initialize() { + if (hr_ == S_FALSE) { + return hr_ = dwriteFactory_->RegisterFontFileLoader( + CDwFontFileLoader::GetLoader()); + } + return hr_; } -CDwGdiTextRenderer::~CDwGdiTextRenderer() -{ - SafeRelease(&pRenderTarget_); - SafeRelease(&pRenderingParams_); +CDwGdiTextRenderer::CDwGdiTextRenderer( + CFX_DIBitmap* pBitmap, + IDWriteBitmapRenderTarget* bitmapRenderTarget, + IDWriteRenderingParams* renderingParams) + : pBitmap_(pBitmap), + pRenderTarget_(SafeAcquire(bitmapRenderTarget)), + pRenderingParams_(SafeAcquire(renderingParams)) {} +CDwGdiTextRenderer::~CDwGdiTextRenderer() { + SafeRelease(&pRenderTarget_); + SafeRelease(&pRenderingParams_); } STDMETHODIMP CDwGdiTextRenderer::DrawGlyphRun( const FX_RECT& text_bbox, @@ -408,60 +374,34 @@ STDMETHODIMP CDwGdiTextRenderer::DrawGlyphRun( FLOAT baselineOriginY, DWRITE_MEASURING_MODE measuringMode, __in DWRITE_GLYPH_RUN const* glyphRun, - const COLORREF& textColor -) -{ - HRESULT hr = S_OK; - if (pMatrix) { - hr = pRenderTarget_->SetCurrentTransform(pMatrix); - if (FAILED(hr)) { - return hr; - } - } - HDC hDC = pRenderTarget_->GetMemoryDC(); - HBITMAP hBitmap = (HBITMAP)::GetCurrentObject(hDC, OBJ_BITMAP); - BITMAP bitmap; - GetObject(hBitmap, sizeof bitmap, &bitmap); - CFX_DIBitmap dib; - dib.Create( - bitmap.bmWidth, - bitmap.bmHeight, - bitmap.bmBitsPixel == 24 ? FXDIB_Rgb : FXDIB_Rgb32, - (uint8_t*)bitmap.bmBits - ); - dib.CompositeBitmap( - text_bbox.left, - text_bbox.top, - text_bbox.Width(), - text_bbox.Height(), - pBitmap_, - text_bbox.left, - text_bbox.top, - FXDIB_BLEND_NORMAL, - NULL - ); - hr = pRenderTarget_->DrawGlyphRun( - baselineOriginX, - baselineOriginY, - measuringMode, - glyphRun, - pRenderingParams_, - textColor - ); + const COLORREF& textColor) { + HRESULT hr = S_OK; + if (pMatrix) { + hr = pRenderTarget_->SetCurrentTransform(pMatrix); if (FAILED(hr)) { - return hr; + return hr; } - pBitmap_->CompositeBitmap( - text_bbox.left, - text_bbox.top, - text_bbox.Width(), - text_bbox.Height(), - &dib, - text_bbox.left, - text_bbox.top, - FXDIB_BLEND_NORMAL, - pClipRgn - ); + } + HDC hDC = pRenderTarget_->GetMemoryDC(); + HBITMAP hBitmap = (HBITMAP)::GetCurrentObject(hDC, OBJ_BITMAP); + BITMAP bitmap; + GetObject(hBitmap, sizeof bitmap, &bitmap); + CFX_DIBitmap dib; + dib.Create(bitmap.bmWidth, bitmap.bmHeight, + bitmap.bmBitsPixel == 24 ? FXDIB_Rgb : FXDIB_Rgb32, + (uint8_t*)bitmap.bmBits); + dib.CompositeBitmap(text_bbox.left, text_bbox.top, text_bbox.Width(), + text_bbox.Height(), pBitmap_, text_bbox.left, + text_bbox.top, FXDIB_BLEND_NORMAL, NULL); + hr = pRenderTarget_->DrawGlyphRun(baselineOriginX, baselineOriginY, + measuringMode, glyphRun, pRenderingParams_, + textColor); + if (FAILED(hr)) { return hr; + } + pBitmap_->CompositeBitmap(text_bbox.left, text_bbox.top, text_bbox.Width(), + text_bbox.Height(), &dib, text_bbox.left, + text_bbox.top, FXDIB_BLEND_NORMAL, pClipRgn); + return hr; } #endif diff --git a/core/src/fxge/win32/fx_win32_gdipext.cpp b/core/src/fxge/win32/fx_win32_gdipext.cpp index d90215a4ea..ce65a26301 100644 --- a/core/src/fxge/win32/fx_win32_gdipext.cpp +++ b/core/src/fxge/win32/fx_win32_gdipext.cpp @@ -9,102 +9,102 @@ #include #include namespace Gdiplus { - using std::min; - using std::max; +using std::min; +using std::max; } // namespace Gdiplus #include #include "../../../include/fxge/fx_ge_win32.h" #include "win32_int.h" using namespace Gdiplus; using namespace Gdiplus::DllExports; -#define GdiFillType2Gdip(fill_type) (fill_type == ALTERNATE ? FillModeAlternate : FillModeWinding) -static CombineMode GdiCombineMode2Gdip(int mode) -{ - switch (mode) { - case RGN_AND: - return CombineModeIntersect; - } - return CombineModeIntersect; +#define GdiFillType2Gdip(fill_type) \ + (fill_type == ALTERNATE ? FillModeAlternate : FillModeWinding) +static CombineMode GdiCombineMode2Gdip(int mode) { + switch (mode) { + case RGN_AND: + return CombineModeIntersect; + } + return CombineModeIntersect; } enum { - FuncId_GdipCreatePath2, - FuncId_GdipSetPenDashStyle, - FuncId_GdipSetPenDashArray, - FuncId_GdipSetPenDashCap197819, - FuncId_GdipSetPenLineJoin, - FuncId_GdipSetPenWidth, - FuncId_GdipCreateFromHDC, - FuncId_GdipSetPageUnit, - FuncId_GdipSetSmoothingMode, - FuncId_GdipCreateSolidFill, - FuncId_GdipFillPath, - FuncId_GdipDeleteBrush, - FuncId_GdipCreatePen1, - FuncId_GdipSetPenMiterLimit, - FuncId_GdipDrawPath, - FuncId_GdipDeletePen, - FuncId_GdipDeletePath, - FuncId_GdipDeleteGraphics, - FuncId_GdipCreateBitmapFromFileICM, - FuncId_GdipCreateBitmapFromStreamICM, - FuncId_GdipGetImageHeight, - FuncId_GdipGetImageWidth, - FuncId_GdipGetImagePixelFormat, - FuncId_GdipBitmapLockBits, - FuncId_GdipGetImagePaletteSize, - FuncId_GdipGetImagePalette, - FuncId_GdipBitmapUnlockBits, - FuncId_GdipDisposeImage, - FuncId_GdipFillRectangle, - FuncId_GdipCreateBitmapFromScan0, - FuncId_GdipSetImagePalette, - FuncId_GdipSetInterpolationMode, - FuncId_GdipDrawImagePointsI, - FuncId_GdipCreateBitmapFromGdiDib, - FuncId_GdiplusStartup, - FuncId_GdipDrawLineI, - FuncId_GdipResetClip, - FuncId_GdipCreatePath, - FuncId_GdipAddPathPath, - FuncId_GdipSetPathFillMode, - FuncId_GdipSetClipPath, - FuncId_GdipGetClip, - FuncId_GdipCreateRegion, - FuncId_GdipGetClipBoundsI, - FuncId_GdipSetClipRegion, - FuncId_GdipWidenPath, - FuncId_GdipAddPathLine, - FuncId_GdipAddPathRectangle, - FuncId_GdipDeleteRegion, - FuncId_GdipGetDC, - FuncId_GdipReleaseDC, - FuncId_GdipSetPenLineCap197819, - FuncId_GdipSetPenDashOffset, - FuncId_GdipResetPath, - FuncId_GdipCreateRegionPath, - FuncId_GdipCreateFont, - FuncId_GdipGetFontSize, - FuncId_GdipCreateFontFamilyFromName, - FuncId_GdipSetTextRenderingHint, - FuncId_GdipDrawDriverString, - FuncId_GdipCreateMatrix2, - FuncId_GdipDeleteMatrix, - FuncId_GdipSetWorldTransform, - FuncId_GdipResetWorldTransform, - FuncId_GdipDeleteFontFamily, - FuncId_GdipDeleteFont, - FuncId_GdipNewPrivateFontCollection, - FuncId_GdipDeletePrivateFontCollection, - FuncId_GdipPrivateAddMemoryFont, - FuncId_GdipGetFontCollectionFamilyList, - FuncId_GdipGetFontCollectionFamilyCount, - FuncId_GdipSetTextContrast, - FuncId_GdipSetPixelOffsetMode, - FuncId_GdipGetImageGraphicsContext, - FuncId_GdipDrawImageI, - FuncId_GdipDrawImageRectI, - FuncId_GdipDrawString, - FuncId_GdipSetPenTransform, + FuncId_GdipCreatePath2, + FuncId_GdipSetPenDashStyle, + FuncId_GdipSetPenDashArray, + FuncId_GdipSetPenDashCap197819, + FuncId_GdipSetPenLineJoin, + FuncId_GdipSetPenWidth, + FuncId_GdipCreateFromHDC, + FuncId_GdipSetPageUnit, + FuncId_GdipSetSmoothingMode, + FuncId_GdipCreateSolidFill, + FuncId_GdipFillPath, + FuncId_GdipDeleteBrush, + FuncId_GdipCreatePen1, + FuncId_GdipSetPenMiterLimit, + FuncId_GdipDrawPath, + FuncId_GdipDeletePen, + FuncId_GdipDeletePath, + FuncId_GdipDeleteGraphics, + FuncId_GdipCreateBitmapFromFileICM, + FuncId_GdipCreateBitmapFromStreamICM, + FuncId_GdipGetImageHeight, + FuncId_GdipGetImageWidth, + FuncId_GdipGetImagePixelFormat, + FuncId_GdipBitmapLockBits, + FuncId_GdipGetImagePaletteSize, + FuncId_GdipGetImagePalette, + FuncId_GdipBitmapUnlockBits, + FuncId_GdipDisposeImage, + FuncId_GdipFillRectangle, + FuncId_GdipCreateBitmapFromScan0, + FuncId_GdipSetImagePalette, + FuncId_GdipSetInterpolationMode, + FuncId_GdipDrawImagePointsI, + FuncId_GdipCreateBitmapFromGdiDib, + FuncId_GdiplusStartup, + FuncId_GdipDrawLineI, + FuncId_GdipResetClip, + FuncId_GdipCreatePath, + FuncId_GdipAddPathPath, + FuncId_GdipSetPathFillMode, + FuncId_GdipSetClipPath, + FuncId_GdipGetClip, + FuncId_GdipCreateRegion, + FuncId_GdipGetClipBoundsI, + FuncId_GdipSetClipRegion, + FuncId_GdipWidenPath, + FuncId_GdipAddPathLine, + FuncId_GdipAddPathRectangle, + FuncId_GdipDeleteRegion, + FuncId_GdipGetDC, + FuncId_GdipReleaseDC, + FuncId_GdipSetPenLineCap197819, + FuncId_GdipSetPenDashOffset, + FuncId_GdipResetPath, + FuncId_GdipCreateRegionPath, + FuncId_GdipCreateFont, + FuncId_GdipGetFontSize, + FuncId_GdipCreateFontFamilyFromName, + FuncId_GdipSetTextRenderingHint, + FuncId_GdipDrawDriverString, + FuncId_GdipCreateMatrix2, + FuncId_GdipDeleteMatrix, + FuncId_GdipSetWorldTransform, + FuncId_GdipResetWorldTransform, + FuncId_GdipDeleteFontFamily, + FuncId_GdipDeleteFont, + FuncId_GdipNewPrivateFontCollection, + FuncId_GdipDeletePrivateFontCollection, + FuncId_GdipPrivateAddMemoryFont, + FuncId_GdipGetFontCollectionFamilyList, + FuncId_GdipGetFontCollectionFamilyCount, + FuncId_GdipSetTextContrast, + FuncId_GdipSetPixelOffsetMode, + FuncId_GdipGetImageGraphicsContext, + FuncId_GdipDrawImageI, + FuncId_GdipDrawImageRectI, + FuncId_GdipDrawString, + FuncId_GdipSetPenTransform, }; static LPCSTR g_GdipFuncNames[] = { "GdipCreatePath2", @@ -186,1070 +186,1335 @@ static LPCSTR g_GdipFuncNames[] = { "GdipDrawString", "GdipSetPenTransform", }; -typedef GpStatus (WINGDIPAPI *FuncType_GdipCreatePath2)(GDIPCONST GpPointF*, GDIPCONST BYTE*, INT, GpFillMode, GpPath **path); -typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenDashStyle)(GpPen *pen, GpDashStyle dashstyle); -typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenDashArray)(GpPen *pen, GDIPCONST REAL *dash, INT count); -typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenDashCap197819)(GpPen *pen, GpDashCap dashCap); -typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenLineJoin)(GpPen *pen, GpLineJoin lineJoin); -typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenWidth)(GpPen *pen, REAL width); -typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateFromHDC)(HDC hdc, GpGraphics **graphics); -typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPageUnit)(GpGraphics *graphics, GpUnit unit); -typedef GpStatus (WINGDIPAPI *FuncType_GdipSetSmoothingMode)(GpGraphics *graphics, SmoothingMode smoothingMode); -typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateSolidFill)(ARGB color, GpSolidFill **brush); -typedef GpStatus (WINGDIPAPI *FuncType_GdipFillPath)(GpGraphics *graphics, GpBrush *brush, GpPath *path); -typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteBrush)(GpBrush *brush); -typedef GpStatus (WINGDIPAPI *FuncType_GdipCreatePen1)(ARGB color, REAL width, GpUnit unit, GpPen **pen); -typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenMiterLimit)(GpPen *pen, REAL miterLimit); -typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawPath)(GpGraphics *graphics, GpPen *pen, GpPath *path); -typedef GpStatus (WINGDIPAPI *FuncType_GdipDeletePen)(GpPen *pen); -typedef GpStatus (WINGDIPAPI *FuncType_GdipDeletePath)(GpPath* path); -typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteGraphics)(GpGraphics *graphics); -typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateBitmapFromFileICM)(GDIPCONST WCHAR* filename, GpBitmap **bitmap); -typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateBitmapFromStreamICM)(IStream* stream, GpBitmap **bitmap); -typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImageWidth)(GpImage *image, UINT *width); -typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImageHeight)(GpImage *image, UINT *height); -typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImagePixelFormat)(GpImage *image, PixelFormat *format); -typedef GpStatus (WINGDIPAPI *FuncType_GdipBitmapLockBits)(GpBitmap* bitmap, GDIPCONST GpRect* rect, UINT flags, PixelFormat format, BitmapData* lockedBitmapData); -typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImagePalette)(GpImage *image, ColorPalette *palette, INT size); -typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImagePaletteSize)(GpImage *image, INT *size); -typedef GpStatus (WINGDIPAPI *FuncType_GdipBitmapUnlockBits)(GpBitmap* bitmap, BitmapData* lockedBitmapData); -typedef GpStatus (WINGDIPAPI *FuncType_GdipDisposeImage)(GpImage *image); -typedef GpStatus (WINGDIPAPI *FuncType_GdipFillRectangle)(GpGraphics *graphics, GpBrush *brush, REAL x, REAL y, REAL width, REAL height); -typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateBitmapFromScan0)(INT width, INT height, INT stride, PixelFormat format, BYTE* scan0, GpBitmap** bitmap); -typedef GpStatus (WINGDIPAPI *FuncType_GdipSetImagePalette)(GpImage *image, GDIPCONST ColorPalette *palette); -typedef GpStatus (WINGDIPAPI *FuncType_GdipSetInterpolationMode)(GpGraphics *graphics, InterpolationMode interpolationMode); -typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawImagePointsI)(GpGraphics *graphics, GpImage *image, GDIPCONST GpPoint *dstpoints, INT count); -typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateBitmapFromGdiDib)(GDIPCONST BITMAPINFO* gdiBitmapInfo, VOID* gdiBitmapData, GpBitmap** bitmap); -typedef Status (WINAPI *FuncType_GdiplusStartup)(OUT uintptr_t *token, const GdiplusStartupInput *input, OUT GdiplusStartupOutput *output); -typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawLineI)(GpGraphics *graphics, GpPen *pen, int x1, int y1, int x2, int y2); -typedef GpStatus (WINGDIPAPI *FuncType_GdipResetClip)(GpGraphics *graphics); -typedef GpStatus (WINGDIPAPI *FuncType_GdipCreatePath)(GpFillMode brushMode, GpPath **path); -typedef GpStatus (WINGDIPAPI *FuncType_GdipAddPathPath)(GpPath *path, GDIPCONST GpPath* addingPath, BOOL connect); -typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPathFillMode)(GpPath *path, GpFillMode fillmode); -typedef GpStatus (WINGDIPAPI *FuncType_GdipSetClipPath)(GpGraphics *graphics, GpPath *path, CombineMode combineMode); -typedef GpStatus (WINGDIPAPI *FuncType_GdipGetClip)(GpGraphics *graphics, GpRegion *region); -typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateRegion)(GpRegion **region); -typedef GpStatus (WINGDIPAPI *FuncType_GdipGetClipBoundsI)(GpGraphics *graphics, GpRect *rect); -typedef GpStatus (WINGDIPAPI *FuncType_GdipSetClipRegion)(GpGraphics *graphics, GpRegion *region, CombineMode combineMode); -typedef GpStatus (WINGDIPAPI *FuncType_GdipWidenPath)(GpPath *nativePath, GpPen *pen, GpMatrix *matrix, REAL flatness); -typedef GpStatus (WINGDIPAPI *FuncType_GdipAddPathLine)(GpPath *path, REAL x1, REAL y1, REAL x2, REAL y2); -typedef GpStatus (WINGDIPAPI *FuncType_GdipAddPathRectangle)(GpPath *path, REAL x, REAL y, REAL width, REAL height); -typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteRegion)(GpRegion *region); -typedef GpStatus (WINGDIPAPI *FuncType_GdipGetDC)(GpGraphics* graphics, HDC * hdc); -typedef GpStatus (WINGDIPAPI *FuncType_GdipReleaseDC)(GpGraphics* graphics, HDC hdc); -typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenLineCap197819)(GpPen *pen, GpLineCap startCap, GpLineCap endCap, GpDashCap dashCap); -typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenDashOffset)(GpPen *pen, REAL offset); -typedef GpStatus (WINGDIPAPI *FuncType_GdipResetPath)(GpPath *path); -typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateRegionPath)(GpPath *path, GpRegion **region); -typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateFont)(GDIPCONST GpFontFamily *fontFamily, REAL emSize, INT style, Unit unit, GpFont **font); -typedef GpStatus (WINGDIPAPI *FuncType_GdipGetFontSize)(GpFont *font, REAL *size); -typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateFontFamilyFromName)(GDIPCONST WCHAR *name, GpFontCollection *fontCollection, GpFontFamily **FontFamily); -typedef GpStatus (WINGDIPAPI *FuncType_GdipSetTextRenderingHint)(GpGraphics *graphics, TextRenderingHint mode); -typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawDriverString)(GpGraphics *graphics, GDIPCONST UINT16 *text, INT length, GDIPCONST GpFont *font, GDIPCONST GpBrush *brush, GDIPCONST PointF *positions, INT flags, GDIPCONST GpMatrix *matrix); -typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateMatrix2)(REAL m11, REAL m12, REAL m21, REAL m22, REAL dx, REAL dy, GpMatrix **matrix); -typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteMatrix)(GpMatrix *matrix); -typedef GpStatus (WINGDIPAPI *FuncType_GdipSetWorldTransform)(GpGraphics *graphics, GpMatrix *matrix); -typedef GpStatus (WINGDIPAPI *FuncType_GdipResetWorldTransform)(GpGraphics *graphics); -typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteFontFamily)(GpFontFamily *FontFamily); -typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteFont)(GpFont* font); -typedef GpStatus (WINGDIPAPI *FuncType_GdipNewPrivateFontCollection)(GpFontCollection** fontCollection); -typedef GpStatus (WINGDIPAPI *FuncType_GdipDeletePrivateFontCollection)(GpFontCollection** fontCollection); -typedef GpStatus (WINGDIPAPI *FuncType_GdipPrivateAddMemoryFont)(GpFontCollection* fontCollection, GDIPCONST void* memory, INT length); -typedef GpStatus (WINGDIPAPI *FuncType_GdipGetFontCollectionFamilyList)(GpFontCollection* fontCollection, INT numSought, GpFontFamily* gpfamilies[], INT* numFound); -typedef GpStatus (WINGDIPAPI *FuncType_GdipGetFontCollectionFamilyCount)(GpFontCollection* fontCollection, INT* numFound); -typedef GpStatus (WINGDIPAPI *FuncType_GdipSetTextContrast)(GpGraphics *graphics, UINT contrast); -typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPixelOffsetMode)(GpGraphics* graphics, PixelOffsetMode pixelOffsetMode); -typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImageGraphicsContext)(GpImage *image, GpGraphics **graphics); -typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawImageI)(GpGraphics *graphics, GpImage *image, INT x, INT y); -typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawImageRectI)(GpGraphics *graphics, GpImage *image, INT x, INT y, INT width, INT height); -typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawString)(GpGraphics *graphics, GDIPCONST WCHAR *string, INT length, GDIPCONST GpFont *font, GDIPCONST RectF *layoutRect, GDIPCONST GpStringFormat *stringFormat, GDIPCONST GpBrush *brush); -typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenTransform)(GpPen *pen, GpMatrix *matrix); -#define CallFunc(funcname) ((FuncType_##funcname)GdiplusExt.m_Functions[FuncId_##funcname]) -typedef HANDLE (__stdcall *FuncType_GdiAddFontMemResourceEx)(PVOID pbFont, DWORD cbFont, PVOID pdv, DWORD *pcFonts); -typedef BOOL (__stdcall *FuncType_GdiRemoveFontMemResourceEx)(HANDLE handle); -void* CGdiplusExt::GdiAddFontMemResourceEx(void *pFontdata, FX_DWORD size, void* pdv, FX_DWORD* num_face) -{ - if (m_pGdiAddFontMemResourceEx) { - return ((FuncType_GdiAddFontMemResourceEx)m_pGdiAddFontMemResourceEx)((PVOID)pFontdata, (DWORD)size, (PVOID)pdv, (DWORD*)num_face); - } - return NULL; +typedef GpStatus(WINGDIPAPI* FuncType_GdipCreatePath2)(GDIPCONST GpPointF*, + GDIPCONST BYTE*, + INT, + GpFillMode, + GpPath** path); +typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPenDashStyle)( + GpPen* pen, + GpDashStyle dashstyle); +typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPenDashArray)(GpPen* pen, + GDIPCONST REAL* dash, + INT count); +typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPenDashCap197819)( + GpPen* pen, + GpDashCap dashCap); +typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPenLineJoin)(GpPen* pen, + GpLineJoin lineJoin); +typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPenWidth)(GpPen* pen, REAL width); +typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateFromHDC)(HDC hdc, + GpGraphics** graphics); +typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPageUnit)(GpGraphics* graphics, + GpUnit unit); +typedef GpStatus(WINGDIPAPI* FuncType_GdipSetSmoothingMode)( + GpGraphics* graphics, + SmoothingMode smoothingMode); +typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateSolidFill)(ARGB color, + GpSolidFill** brush); +typedef GpStatus(WINGDIPAPI* FuncType_GdipFillPath)(GpGraphics* graphics, + GpBrush* brush, + GpPath* path); +typedef GpStatus(WINGDIPAPI* FuncType_GdipDeleteBrush)(GpBrush* brush); +typedef GpStatus(WINGDIPAPI* FuncType_GdipCreatePen1)(ARGB color, + REAL width, + GpUnit unit, + GpPen** pen); +typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPenMiterLimit)(GpPen* pen, + REAL miterLimit); +typedef GpStatus(WINGDIPAPI* FuncType_GdipDrawPath)(GpGraphics* graphics, + GpPen* pen, + GpPath* path); +typedef GpStatus(WINGDIPAPI* FuncType_GdipDeletePen)(GpPen* pen); +typedef GpStatus(WINGDIPAPI* FuncType_GdipDeletePath)(GpPath* path); +typedef GpStatus(WINGDIPAPI* FuncType_GdipDeleteGraphics)(GpGraphics* graphics); +typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateBitmapFromFileICM)( + GDIPCONST WCHAR* filename, + GpBitmap** bitmap); +typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateBitmapFromStreamICM)( + IStream* stream, + GpBitmap** bitmap); +typedef GpStatus(WINGDIPAPI* FuncType_GdipGetImageWidth)(GpImage* image, + UINT* width); +typedef GpStatus(WINGDIPAPI* FuncType_GdipGetImageHeight)(GpImage* image, + UINT* height); +typedef GpStatus(WINGDIPAPI* FuncType_GdipGetImagePixelFormat)( + GpImage* image, + PixelFormat* format); +typedef GpStatus(WINGDIPAPI* FuncType_GdipBitmapLockBits)( + GpBitmap* bitmap, + GDIPCONST GpRect* rect, + UINT flags, + PixelFormat format, + BitmapData* lockedBitmapData); +typedef GpStatus(WINGDIPAPI* FuncType_GdipGetImagePalette)( + GpImage* image, + ColorPalette* palette, + INT size); +typedef GpStatus(WINGDIPAPI* FuncType_GdipGetImagePaletteSize)(GpImage* image, + INT* size); +typedef GpStatus(WINGDIPAPI* FuncType_GdipBitmapUnlockBits)( + GpBitmap* bitmap, + BitmapData* lockedBitmapData); +typedef GpStatus(WINGDIPAPI* FuncType_GdipDisposeImage)(GpImage* image); +typedef GpStatus(WINGDIPAPI* FuncType_GdipFillRectangle)(GpGraphics* graphics, + GpBrush* brush, + REAL x, + REAL y, + REAL width, + REAL height); +typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateBitmapFromScan0)( + INT width, + INT height, + INT stride, + PixelFormat format, + BYTE* scan0, + GpBitmap** bitmap); +typedef GpStatus(WINGDIPAPI* FuncType_GdipSetImagePalette)( + GpImage* image, + GDIPCONST ColorPalette* palette); +typedef GpStatus(WINGDIPAPI* FuncType_GdipSetInterpolationMode)( + GpGraphics* graphics, + InterpolationMode interpolationMode); +typedef GpStatus(WINGDIPAPI* FuncType_GdipDrawImagePointsI)( + GpGraphics* graphics, + GpImage* image, + GDIPCONST GpPoint* dstpoints, + INT count); +typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateBitmapFromGdiDib)( + GDIPCONST BITMAPINFO* gdiBitmapInfo, + VOID* gdiBitmapData, + GpBitmap** bitmap); +typedef Status(WINAPI* FuncType_GdiplusStartup)( + OUT uintptr_t* token, + const GdiplusStartupInput* input, + OUT GdiplusStartupOutput* output); +typedef GpStatus(WINGDIPAPI* FuncType_GdipDrawLineI)(GpGraphics* graphics, + GpPen* pen, + int x1, + int y1, + int x2, + int y2); +typedef GpStatus(WINGDIPAPI* FuncType_GdipResetClip)(GpGraphics* graphics); +typedef GpStatus(WINGDIPAPI* FuncType_GdipCreatePath)(GpFillMode brushMode, + GpPath** path); +typedef GpStatus(WINGDIPAPI* FuncType_GdipAddPathPath)( + GpPath* path, + GDIPCONST GpPath* addingPath, + BOOL connect); +typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPathFillMode)(GpPath* path, + GpFillMode fillmode); +typedef GpStatus(WINGDIPAPI* FuncType_GdipSetClipPath)(GpGraphics* graphics, + GpPath* path, + CombineMode combineMode); +typedef GpStatus(WINGDIPAPI* FuncType_GdipGetClip)(GpGraphics* graphics, + GpRegion* region); +typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateRegion)(GpRegion** region); +typedef GpStatus(WINGDIPAPI* FuncType_GdipGetClipBoundsI)(GpGraphics* graphics, + GpRect* rect); +typedef GpStatus(WINGDIPAPI* FuncType_GdipSetClipRegion)( + GpGraphics* graphics, + GpRegion* region, + CombineMode combineMode); +typedef GpStatus(WINGDIPAPI* FuncType_GdipWidenPath)(GpPath* nativePath, + GpPen* pen, + GpMatrix* matrix, + REAL flatness); +typedef GpStatus(WINGDIPAPI* FuncType_GdipAddPathLine)(GpPath* path, + REAL x1, + REAL y1, + REAL x2, + REAL y2); +typedef GpStatus(WINGDIPAPI* FuncType_GdipAddPathRectangle)(GpPath* path, + REAL x, + REAL y, + REAL width, + REAL height); +typedef GpStatus(WINGDIPAPI* FuncType_GdipDeleteRegion)(GpRegion* region); +typedef GpStatus(WINGDIPAPI* FuncType_GdipGetDC)(GpGraphics* graphics, + HDC* hdc); +typedef GpStatus(WINGDIPAPI* FuncType_GdipReleaseDC)(GpGraphics* graphics, + HDC hdc); +typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPenLineCap197819)( + GpPen* pen, + GpLineCap startCap, + GpLineCap endCap, + GpDashCap dashCap); +typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPenDashOffset)(GpPen* pen, + REAL offset); +typedef GpStatus(WINGDIPAPI* FuncType_GdipResetPath)(GpPath* path); +typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateRegionPath)(GpPath* path, + GpRegion** region); +typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateFont)( + GDIPCONST GpFontFamily* fontFamily, + REAL emSize, + INT style, + Unit unit, + GpFont** font); +typedef GpStatus(WINGDIPAPI* FuncType_GdipGetFontSize)(GpFont* font, + REAL* size); +typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateFontFamilyFromName)( + GDIPCONST WCHAR* name, + GpFontCollection* fontCollection, + GpFontFamily** FontFamily); +typedef GpStatus(WINGDIPAPI* FuncType_GdipSetTextRenderingHint)( + GpGraphics* graphics, + TextRenderingHint mode); +typedef GpStatus(WINGDIPAPI* FuncType_GdipDrawDriverString)( + GpGraphics* graphics, + GDIPCONST UINT16* text, + INT length, + GDIPCONST GpFont* font, + GDIPCONST GpBrush* brush, + GDIPCONST PointF* positions, + INT flags, + GDIPCONST GpMatrix* matrix); +typedef GpStatus(WINGDIPAPI* FuncType_GdipCreateMatrix2)(REAL m11, + REAL m12, + REAL m21, + REAL m22, + REAL dx, + REAL dy, + GpMatrix** matrix); +typedef GpStatus(WINGDIPAPI* FuncType_GdipDeleteMatrix)(GpMatrix* matrix); +typedef GpStatus(WINGDIPAPI* FuncType_GdipSetWorldTransform)( + GpGraphics* graphics, + GpMatrix* matrix); +typedef GpStatus(WINGDIPAPI* FuncType_GdipResetWorldTransform)( + GpGraphics* graphics); +typedef GpStatus(WINGDIPAPI* FuncType_GdipDeleteFontFamily)( + GpFontFamily* FontFamily); +typedef GpStatus(WINGDIPAPI* FuncType_GdipDeleteFont)(GpFont* font); +typedef GpStatus(WINGDIPAPI* FuncType_GdipNewPrivateFontCollection)( + GpFontCollection** fontCollection); +typedef GpStatus(WINGDIPAPI* FuncType_GdipDeletePrivateFontCollection)( + GpFontCollection** fontCollection); +typedef GpStatus(WINGDIPAPI* FuncType_GdipPrivateAddMemoryFont)( + GpFontCollection* fontCollection, + GDIPCONST void* memory, + INT length); +typedef GpStatus(WINGDIPAPI* FuncType_GdipGetFontCollectionFamilyList)( + GpFontCollection* fontCollection, + INT numSought, + GpFontFamily* gpfamilies[], + INT* numFound); +typedef GpStatus(WINGDIPAPI* FuncType_GdipGetFontCollectionFamilyCount)( + GpFontCollection* fontCollection, + INT* numFound); +typedef GpStatus(WINGDIPAPI* FuncType_GdipSetTextContrast)(GpGraphics* graphics, + UINT contrast); +typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPixelOffsetMode)( + GpGraphics* graphics, + PixelOffsetMode pixelOffsetMode); +typedef GpStatus(WINGDIPAPI* FuncType_GdipGetImageGraphicsContext)( + GpImage* image, + GpGraphics** graphics); +typedef GpStatus(WINGDIPAPI* FuncType_GdipDrawImageI)(GpGraphics* graphics, + GpImage* image, + INT x, + INT y); +typedef GpStatus(WINGDIPAPI* FuncType_GdipDrawImageRectI)(GpGraphics* graphics, + GpImage* image, + INT x, + INT y, + INT width, + INT height); +typedef GpStatus(WINGDIPAPI* FuncType_GdipDrawString)( + GpGraphics* graphics, + GDIPCONST WCHAR* string, + INT length, + GDIPCONST GpFont* font, + GDIPCONST RectF* layoutRect, + GDIPCONST GpStringFormat* stringFormat, + GDIPCONST GpBrush* brush); +typedef GpStatus(WINGDIPAPI* FuncType_GdipSetPenTransform)(GpPen* pen, + GpMatrix* matrix); +#define CallFunc(funcname) \ + ((FuncType_##funcname)GdiplusExt.m_Functions[FuncId_##funcname]) +typedef HANDLE(__stdcall* FuncType_GdiAddFontMemResourceEx)(PVOID pbFont, + DWORD cbFont, + PVOID pdv, + DWORD* pcFonts); +typedef BOOL(__stdcall* FuncType_GdiRemoveFontMemResourceEx)(HANDLE handle); +void* CGdiplusExt::GdiAddFontMemResourceEx(void* pFontdata, + FX_DWORD size, + void* pdv, + FX_DWORD* num_face) { + if (m_pGdiAddFontMemResourceEx) { + return ((FuncType_GdiAddFontMemResourceEx)m_pGdiAddFontMemResourceEx)( + (PVOID)pFontdata, (DWORD)size, (PVOID)pdv, (DWORD*)num_face); + } + return NULL; } -FX_BOOL CGdiplusExt::GdiRemoveFontMemResourceEx(void* handle) -{ - if (m_pGdiRemoveFontMemResourseEx) { - return ((FuncType_GdiRemoveFontMemResourceEx)m_pGdiRemoveFontMemResourseEx)((HANDLE)handle); - } - return FALSE; +FX_BOOL CGdiplusExt::GdiRemoveFontMemResourceEx(void* handle) { + if (m_pGdiRemoveFontMemResourseEx) { + return ((FuncType_GdiRemoveFontMemResourceEx)m_pGdiRemoveFontMemResourseEx)( + (HANDLE)handle); + } + return FALSE; } -static GpBrush* _GdipCreateBrush(DWORD argb) -{ - CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - GpSolidFill* solidBrush = NULL; - CallFunc(GdipCreateSolidFill)((ARGB)argb, &solidBrush); - return solidBrush; +static GpBrush* _GdipCreateBrush(DWORD argb) { + CGdiplusExt& GdiplusExt = + ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; + GpSolidFill* solidBrush = NULL; + CallFunc(GdipCreateSolidFill)((ARGB)argb, &solidBrush); + return solidBrush; } -static CFX_DIBitmap* _StretchMonoToGray(int dest_width, int dest_height, - const CFX_DIBitmap* pSource, FX_RECT* pClipRect) -{ - FX_BOOL bFlipX = dest_width < 0; - if (bFlipX) { - dest_width = -dest_width; - } - FX_BOOL bFlipY = dest_height < 0; - if (bFlipY) { - dest_height = -dest_height; - } - int result_width = pClipRect->Width(); - int result_height = pClipRect->Height(); - int result_pitch = (result_width + 3) / 4 * 4; - CFX_DIBitmap* pStretched = new CFX_DIBitmap; - if (!pStretched->Create(result_width, result_height, FXDIB_8bppRgb)) { - delete pStretched; - return NULL; - } - LPBYTE dest_buf = pStretched->GetBuffer(); - int src_width = pSource->GetWidth(); - int src_height = pSource->GetHeight(); - int src_count = src_width * src_height; - int dest_count = dest_width * dest_height; - int ratio = 255 * dest_count / src_count; - int y_unit = src_height / dest_height; - int x_unit = src_width / dest_width; - int area_unit = y_unit * x_unit; - LPBYTE src_buf = pSource->GetBuffer(); - int src_pitch = pSource->GetPitch(); - for (int dest_y = 0; dest_y < result_height; dest_y ++) { - LPBYTE dest_scan = dest_buf + dest_y * result_pitch; - int src_y_start = bFlipY ? (dest_height - 1 - dest_y - pClipRect->top) : (dest_y + pClipRect->top); - src_y_start = src_y_start * src_height / dest_height; - LPBYTE src_scan = src_buf + src_y_start * src_pitch; - for (int dest_x = 0; dest_x < result_width; dest_x ++) { - int sum = 0; - int src_x_start = bFlipX ? (dest_width - 1 - dest_x - pClipRect->left) : (dest_x + pClipRect->left); - src_x_start = src_x_start * src_width / dest_width; - int src_x_end = src_x_start + x_unit; - LPBYTE src_line = src_scan; - for (int src_y = 0; src_y < y_unit; src_y ++) { - for (int src_x = src_x_start; src_x < src_x_end; src_x ++) { - if (!(src_line[src_x / 8] & (1 << (7 - src_x % 8)))) { - sum += 255; - } - } - src_line += src_pitch; - } - dest_scan[dest_x] = 255 - sum / area_unit; +static CFX_DIBitmap* _StretchMonoToGray(int dest_width, + int dest_height, + const CFX_DIBitmap* pSource, + FX_RECT* pClipRect) { + FX_BOOL bFlipX = dest_width < 0; + if (bFlipX) { + dest_width = -dest_width; + } + FX_BOOL bFlipY = dest_height < 0; + if (bFlipY) { + dest_height = -dest_height; + } + int result_width = pClipRect->Width(); + int result_height = pClipRect->Height(); + int result_pitch = (result_width + 3) / 4 * 4; + CFX_DIBitmap* pStretched = new CFX_DIBitmap; + if (!pStretched->Create(result_width, result_height, FXDIB_8bppRgb)) { + delete pStretched; + return NULL; + } + LPBYTE dest_buf = pStretched->GetBuffer(); + int src_width = pSource->GetWidth(); + int src_height = pSource->GetHeight(); + int src_count = src_width * src_height; + int dest_count = dest_width * dest_height; + int ratio = 255 * dest_count / src_count; + int y_unit = src_height / dest_height; + int x_unit = src_width / dest_width; + int area_unit = y_unit * x_unit; + LPBYTE src_buf = pSource->GetBuffer(); + int src_pitch = pSource->GetPitch(); + for (int dest_y = 0; dest_y < result_height; dest_y++) { + LPBYTE dest_scan = dest_buf + dest_y * result_pitch; + int src_y_start = bFlipY ? (dest_height - 1 - dest_y - pClipRect->top) + : (dest_y + pClipRect->top); + src_y_start = src_y_start * src_height / dest_height; + LPBYTE src_scan = src_buf + src_y_start * src_pitch; + for (int dest_x = 0; dest_x < result_width; dest_x++) { + int sum = 0; + int src_x_start = bFlipX ? (dest_width - 1 - dest_x - pClipRect->left) + : (dest_x + pClipRect->left); + src_x_start = src_x_start * src_width / dest_width; + int src_x_end = src_x_start + x_unit; + LPBYTE src_line = src_scan; + for (int src_y = 0; src_y < y_unit; src_y++) { + for (int src_x = src_x_start; src_x < src_x_end; src_x++) { + if (!(src_line[src_x / 8] & (1 << (7 - src_x % 8)))) { + sum += 255; + } } + src_line += src_pitch; + } + dest_scan[dest_x] = 255 - sum / area_unit; } - return pStretched; + } + return pStretched; } -static void OutputImageMask(GpGraphics* pGraphics, BOOL bMonoDevice, const CFX_DIBitmap* pBitmap, int dest_left, int dest_top, - int dest_width, int dest_height, FX_ARGB argb, const FX_RECT* pClipRect) -{ - ASSERT(pBitmap->GetBPP() == 1); - CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - int src_width = pBitmap->GetWidth(), src_height = pBitmap->GetHeight(); - int src_pitch = pBitmap->GetPitch(); - uint8_t* scan0 = pBitmap->GetBuffer(); - if (src_width == 1 && src_height == 1) { - if ((scan0[0] & 0x80) == 0) { - return; - } - GpSolidFill* solidBrush; - CallFunc(GdipCreateSolidFill)((ARGB)argb, &solidBrush); - if (dest_width < 0) { - dest_width = -dest_width; - dest_left -= dest_width; - } - if (dest_height < 0) { - dest_height = -dest_height; - dest_top -= dest_height; - } - CallFunc(GdipFillRectangle)(pGraphics, solidBrush, (float)dest_left, (float)dest_top, - (float)dest_width, (float)dest_height); - CallFunc(GdipDeleteBrush)(solidBrush); - return; - } - if (!bMonoDevice && abs(dest_width) < src_width && abs(dest_height) < src_height) { - FX_RECT image_rect(dest_left, dest_top, dest_left + dest_width, dest_top + dest_height); - image_rect.Normalize(); - FX_RECT image_clip = image_rect; - image_clip.Intersect(*pClipRect); - if (image_clip.IsEmpty()) { - return; - } - image_clip.Offset(-image_rect.left, -image_rect.top); - CFX_DIBitmap* pStretched = NULL; - if (src_width * src_height > 10000) { - pStretched = _StretchMonoToGray(dest_width, dest_height, pBitmap, &image_clip); - } else { - pStretched = pBitmap->StretchTo(dest_width, dest_height, FALSE, &image_clip); - } - GpBitmap* bitmap; - CallFunc(GdipCreateBitmapFromScan0)(image_clip.Width(), image_clip.Height(), - (image_clip.Width() + 3) / 4 * 4, PixelFormat8bppIndexed, pStretched->GetBuffer(), &bitmap); - int a, r, g, b; - ArgbDecode(argb, a, r, g, b); - UINT pal[258]; - pal[0] = 0; - pal[1] = 256; - for (int i = 0; i < 256; i ++) { - pal[i + 2] = ArgbEncode(i * a / 255, r, g, b); - } - CallFunc(GdipSetImagePalette)(bitmap, (ColorPalette*)pal); - CallFunc(GdipDrawImageI)(pGraphics, bitmap, image_rect.left + image_clip.left, - image_rect.top + image_clip.top); - CallFunc(GdipDisposeImage)(bitmap); - delete pStretched; - return; - } - GpBitmap* bitmap; - CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch, PixelFormat1bppIndexed, scan0, &bitmap); - UINT palette[4] = { PaletteFlagsHasAlpha, 2, 0, argb }; - CallFunc(GdipSetImagePalette)(bitmap, (ColorPalette*)palette); - Point destinationPoints[] = { - Point(dest_left, dest_top), - Point(dest_left + dest_width, dest_top), - Point(dest_left, dest_top + dest_height) - }; - CallFunc(GdipDrawImagePointsI)(pGraphics, bitmap, destinationPoints, 3); - CallFunc(GdipDisposeImage)(bitmap); -} -static void OutputImage(GpGraphics* pGraphics, const CFX_DIBitmap* pBitmap, const FX_RECT* pSrcRect, - int dest_left, int dest_top, int dest_width, int dest_height) -{ - int src_width = pSrcRect->Width(), src_height = pSrcRect->Height(); - CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - if (pBitmap->GetBPP() == 1 && (pSrcRect->left % 8)) { - FX_RECT new_rect(0, 0, src_width, src_height); - CFX_DIBitmap* pCloned = pBitmap->Clone(pSrcRect); - if (!pCloned) { - return; - } - OutputImage(pGraphics, pCloned, &new_rect, dest_left, dest_top, dest_width, dest_height); - delete pCloned; - return; - } - int src_pitch = pBitmap->GetPitch(); - uint8_t* scan0 = pBitmap->GetBuffer() + pSrcRect->top * src_pitch + pBitmap->GetBPP() * pSrcRect->left / 8; - GpBitmap* bitmap = NULL; - switch (pBitmap->GetFormat()) { - case FXDIB_Argb: - CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch, - PixelFormat32bppARGB, scan0, &bitmap); - break; - case FXDIB_Rgb32: - CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch, - PixelFormat32bppRGB, scan0, &bitmap); - break; - case FXDIB_Rgb: - CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch, - PixelFormat24bppRGB, scan0, &bitmap); - break; - case FXDIB_8bppRgb: { - CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch, - PixelFormat8bppIndexed, scan0, &bitmap); - UINT pal[258]; - pal[0] = 0; - pal[1] = 256; - for (int i = 0; i < 256; i ++) { - pal[i + 2] = pBitmap->GetPaletteEntry(i); - } - CallFunc(GdipSetImagePalette)(bitmap, (ColorPalette*)pal); - break; - } - case FXDIB_1bppRgb: { - CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch, - PixelFormat1bppIndexed, scan0, &bitmap); - break; - } +static void OutputImageMask(GpGraphics* pGraphics, + BOOL bMonoDevice, + const CFX_DIBitmap* pBitmap, + int dest_left, + int dest_top, + int dest_width, + int dest_height, + FX_ARGB argb, + const FX_RECT* pClipRect) { + ASSERT(pBitmap->GetBPP() == 1); + CGdiplusExt& GdiplusExt = + ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; + int src_width = pBitmap->GetWidth(), src_height = pBitmap->GetHeight(); + int src_pitch = pBitmap->GetPitch(); + uint8_t* scan0 = pBitmap->GetBuffer(); + if (src_width == 1 && src_height == 1) { + if ((scan0[0] & 0x80) == 0) { + return; + } + GpSolidFill* solidBrush; + CallFunc(GdipCreateSolidFill)((ARGB)argb, &solidBrush); + if (dest_width < 0) { + dest_width = -dest_width; + dest_left -= dest_width; } if (dest_height < 0) { - dest_height --; - } - if (dest_width < 0) { - dest_width --; + dest_height = -dest_height; + dest_top -= dest_height; + } + CallFunc(GdipFillRectangle)(pGraphics, solidBrush, (float)dest_left, + (float)dest_top, (float)dest_width, + (float)dest_height); + CallFunc(GdipDeleteBrush)(solidBrush); + return; + } + if (!bMonoDevice && abs(dest_width) < src_width && + abs(dest_height) < src_height) { + FX_RECT image_rect(dest_left, dest_top, dest_left + dest_width, + dest_top + dest_height); + image_rect.Normalize(); + FX_RECT image_clip = image_rect; + image_clip.Intersect(*pClipRect); + if (image_clip.IsEmpty()) { + return; + } + image_clip.Offset(-image_rect.left, -image_rect.top); + CFX_DIBitmap* pStretched = NULL; + if (src_width * src_height > 10000) { + pStretched = + _StretchMonoToGray(dest_width, dest_height, pBitmap, &image_clip); + } else { + pStretched = + pBitmap->StretchTo(dest_width, dest_height, FALSE, &image_clip); } - Point destinationPoints[] = { - Point(dest_left, dest_top), - Point(dest_left + dest_width, dest_top), - Point(dest_left, dest_top + dest_height) - }; - CallFunc(GdipDrawImagePointsI)(pGraphics, bitmap, destinationPoints, 3); + GpBitmap* bitmap; + CallFunc(GdipCreateBitmapFromScan0)(image_clip.Width(), image_clip.Height(), + (image_clip.Width() + 3) / 4 * 4, + PixelFormat8bppIndexed, + pStretched->GetBuffer(), &bitmap); + int a, r, g, b; + ArgbDecode(argb, a, r, g, b); + UINT pal[258]; + pal[0] = 0; + pal[1] = 256; + for (int i = 0; i < 256; i++) { + pal[i + 2] = ArgbEncode(i * a / 255, r, g, b); + } + CallFunc(GdipSetImagePalette)(bitmap, (ColorPalette*)pal); + CallFunc(GdipDrawImageI)(pGraphics, bitmap, + image_rect.left + image_clip.left, + image_rect.top + image_clip.top); CallFunc(GdipDisposeImage)(bitmap); + delete pStretched; + return; + } + GpBitmap* bitmap; + CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch, + PixelFormat1bppIndexed, scan0, &bitmap); + UINT palette[4] = {PaletteFlagsHasAlpha, 2, 0, argb}; + CallFunc(GdipSetImagePalette)(bitmap, (ColorPalette*)palette); + Point destinationPoints[] = {Point(dest_left, dest_top), + Point(dest_left + dest_width, dest_top), + Point(dest_left, dest_top + dest_height)}; + CallFunc(GdipDrawImagePointsI)(pGraphics, bitmap, destinationPoints, 3); + CallFunc(GdipDisposeImage)(bitmap); } -CGdiplusExt::CGdiplusExt() -{ - m_hModule = NULL; - m_GdiModule = NULL; - for (int i = 0; i < sizeof g_GdipFuncNames / sizeof(LPCSTR); i ++) { - m_Functions[i] = NULL; - } - m_pGdiAddFontMemResourceEx = NULL; - m_pGdiRemoveFontMemResourseEx = NULL; +static void OutputImage(GpGraphics* pGraphics, + const CFX_DIBitmap* pBitmap, + const FX_RECT* pSrcRect, + int dest_left, + int dest_top, + int dest_width, + int dest_height) { + int src_width = pSrcRect->Width(), src_height = pSrcRect->Height(); + CGdiplusExt& GdiplusExt = + ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; + if (pBitmap->GetBPP() == 1 && (pSrcRect->left % 8)) { + FX_RECT new_rect(0, 0, src_width, src_height); + CFX_DIBitmap* pCloned = pBitmap->Clone(pSrcRect); + if (!pCloned) { + return; + } + OutputImage(pGraphics, pCloned, &new_rect, dest_left, dest_top, dest_width, + dest_height); + delete pCloned; + return; + } + int src_pitch = pBitmap->GetPitch(); + uint8_t* scan0 = pBitmap->GetBuffer() + pSrcRect->top * src_pitch + + pBitmap->GetBPP() * pSrcRect->left / 8; + GpBitmap* bitmap = NULL; + switch (pBitmap->GetFormat()) { + case FXDIB_Argb: + CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch, + PixelFormat32bppARGB, scan0, &bitmap); + break; + case FXDIB_Rgb32: + CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch, + PixelFormat32bppRGB, scan0, &bitmap); + break; + case FXDIB_Rgb: + CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch, + PixelFormat24bppRGB, scan0, &bitmap); + break; + case FXDIB_8bppRgb: { + CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch, + PixelFormat8bppIndexed, scan0, + &bitmap); + UINT pal[258]; + pal[0] = 0; + pal[1] = 256; + for (int i = 0; i < 256; i++) { + pal[i + 2] = pBitmap->GetPaletteEntry(i); + } + CallFunc(GdipSetImagePalette)(bitmap, (ColorPalette*)pal); + break; + } + case FXDIB_1bppRgb: { + CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch, + PixelFormat1bppIndexed, scan0, + &bitmap); + break; + } + } + if (dest_height < 0) { + dest_height--; + } + if (dest_width < 0) { + dest_width--; + } + Point destinationPoints[] = {Point(dest_left, dest_top), + Point(dest_left + dest_width, dest_top), + Point(dest_left, dest_top + dest_height)}; + CallFunc(GdipDrawImagePointsI)(pGraphics, bitmap, destinationPoints, 3); + CallFunc(GdipDisposeImage)(bitmap); } -void CGdiplusExt::Load() -{ - CFX_ByteString strPlusPath = ""; - FX_CHAR buf[MAX_PATH]; - GetSystemDirectoryA(buf, MAX_PATH); - strPlusPath += buf; - strPlusPath += "\\"; - strPlusPath += "GDIPLUS.DLL"; - m_hModule = LoadLibraryA(strPlusPath); - if (m_hModule == NULL) { - return; - } - for (int i = 0; i < sizeof g_GdipFuncNames / sizeof(LPCSTR); i ++) { - m_Functions[i] = GetProcAddress(m_hModule, g_GdipFuncNames[i]); - if (m_Functions[i] == NULL) { - m_hModule = NULL; - return; - } - } - uintptr_t gdiplusToken; - GdiplusStartupInput gdiplusStartupInput; - ((FuncType_GdiplusStartup)m_Functions[FuncId_GdiplusStartup])(&gdiplusToken, &gdiplusStartupInput, NULL); - m_GdiModule = LoadLibraryA("GDI32.DLL"); - if (m_GdiModule == NULL) { - return; - } - m_pGdiAddFontMemResourceEx = GetProcAddress(m_GdiModule, "AddFontMemResourceEx"); - m_pGdiRemoveFontMemResourseEx = GetProcAddress(m_GdiModule, "RemoveFontMemResourceEx"); +CGdiplusExt::CGdiplusExt() { + m_hModule = NULL; + m_GdiModule = NULL; + for (int i = 0; i < sizeof g_GdipFuncNames / sizeof(LPCSTR); i++) { + m_Functions[i] = NULL; + } + m_pGdiAddFontMemResourceEx = NULL; + m_pGdiRemoveFontMemResourseEx = NULL; } -CGdiplusExt::~CGdiplusExt() -{ +void CGdiplusExt::Load() { + CFX_ByteString strPlusPath = ""; + FX_CHAR buf[MAX_PATH]; + GetSystemDirectoryA(buf, MAX_PATH); + strPlusPath += buf; + strPlusPath += "\\"; + strPlusPath += "GDIPLUS.DLL"; + m_hModule = LoadLibraryA(strPlusPath); + if (m_hModule == NULL) { + return; + } + for (int i = 0; i < sizeof g_GdipFuncNames / sizeof(LPCSTR); i++) { + m_Functions[i] = GetProcAddress(m_hModule, g_GdipFuncNames[i]); + if (m_Functions[i] == NULL) { + m_hModule = NULL; + return; + } + } + uintptr_t gdiplusToken; + GdiplusStartupInput gdiplusStartupInput; + ((FuncType_GdiplusStartup)m_Functions[FuncId_GdiplusStartup])( + &gdiplusToken, &gdiplusStartupInput, NULL); + m_GdiModule = LoadLibraryA("GDI32.DLL"); + if (m_GdiModule == NULL) { + return; + } + m_pGdiAddFontMemResourceEx = + GetProcAddress(m_GdiModule, "AddFontMemResourceEx"); + m_pGdiRemoveFontMemResourseEx = + GetProcAddress(m_GdiModule, "RemoveFontMemResourceEx"); } -LPVOID CGdiplusExt::LoadMemFont(LPBYTE pData, FX_DWORD size) -{ - GpFontCollection* pCollection = NULL; - CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - CallFunc(GdipNewPrivateFontCollection)(&pCollection); - GpStatus status = CallFunc(GdipPrivateAddMemoryFont)(pCollection, pData, size); - if (status == Ok) { - return pCollection; - } - CallFunc(GdipDeletePrivateFontCollection)(&pCollection); - return NULL; +CGdiplusExt::~CGdiplusExt() {} +LPVOID CGdiplusExt::LoadMemFont(LPBYTE pData, FX_DWORD size) { + GpFontCollection* pCollection = NULL; + CGdiplusExt& GdiplusExt = + ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; + CallFunc(GdipNewPrivateFontCollection)(&pCollection); + GpStatus status = + CallFunc(GdipPrivateAddMemoryFont)(pCollection, pData, size); + if (status == Ok) { + return pCollection; + } + CallFunc(GdipDeletePrivateFontCollection)(&pCollection); + return NULL; } -void CGdiplusExt::DeleteMemFont(LPVOID pCollection) -{ - CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - CallFunc(GdipDeletePrivateFontCollection)((GpFontCollection**)&pCollection); +void CGdiplusExt::DeleteMemFont(LPVOID pCollection) { + CGdiplusExt& GdiplusExt = + ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; + CallFunc(GdipDeletePrivateFontCollection)((GpFontCollection**)&pCollection); } -FX_BOOL CGdiplusExt::GdipCreateBitmap(CFX_DIBitmap* pBitmap, void**bitmap) -{ - CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - PixelFormat format; - switch (pBitmap->GetFormat()) { - case FXDIB_Rgb: - format = PixelFormat24bppRGB; - break; - case FXDIB_Rgb32: - format = PixelFormat32bppRGB; - break; - case FXDIB_Argb: - format = PixelFormat32bppARGB; - break; - default: - return FALSE; - } - GpStatus status = CallFunc(GdipCreateBitmapFromScan0)(pBitmap->GetWidth(), pBitmap->GetHeight(), - pBitmap->GetPitch(), format, pBitmap->GetBuffer(), (GpBitmap**)bitmap); - if (status == Ok) { - return TRUE; - } - return FALSE; +FX_BOOL CGdiplusExt::GdipCreateBitmap(CFX_DIBitmap* pBitmap, void** bitmap) { + CGdiplusExt& GdiplusExt = + ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; + PixelFormat format; + switch (pBitmap->GetFormat()) { + case FXDIB_Rgb: + format = PixelFormat24bppRGB; + break; + case FXDIB_Rgb32: + format = PixelFormat32bppRGB; + break; + case FXDIB_Argb: + format = PixelFormat32bppARGB; + break; + default: + return FALSE; + } + GpStatus status = CallFunc(GdipCreateBitmapFromScan0)( + pBitmap->GetWidth(), pBitmap->GetHeight(), pBitmap->GetPitch(), format, + pBitmap->GetBuffer(), (GpBitmap**)bitmap); + if (status == Ok) { + return TRUE; + } + return FALSE; } -FX_BOOL CGdiplusExt::GdipCreateFromImage(void* bitmap, void** graphics) -{ - CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - GpStatus status = CallFunc(GdipGetImageGraphicsContext)((GpBitmap*)bitmap, (GpGraphics**)graphics); - if (status == Ok) { - return TRUE; - } - return FALSE; +FX_BOOL CGdiplusExt::GdipCreateFromImage(void* bitmap, void** graphics) { + CGdiplusExt& GdiplusExt = + ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; + GpStatus status = CallFunc(GdipGetImageGraphicsContext)( + (GpBitmap*)bitmap, (GpGraphics**)graphics); + if (status == Ok) { + return TRUE; + } + return FALSE; } -FX_BOOL CGdiplusExt::GdipCreateFontFamilyFromName(const FX_WCHAR* name, void* pFontCollection, void**pFamily) -{ - CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - GpStatus status = CallFunc(GdipCreateFontFamilyFromName)((GDIPCONST WCHAR *)name, (GpFontCollection*)pFontCollection, (GpFontFamily**)pFamily); - if (status == Ok) { - return TRUE; - } - return FALSE; +FX_BOOL CGdiplusExt::GdipCreateFontFamilyFromName(const FX_WCHAR* name, + void* pFontCollection, + void** pFamily) { + CGdiplusExt& GdiplusExt = + ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; + GpStatus status = CallFunc(GdipCreateFontFamilyFromName)( + (GDIPCONST WCHAR*)name, (GpFontCollection*)pFontCollection, + (GpFontFamily**)pFamily); + if (status == Ok) { + return TRUE; + } + return FALSE; } -FX_BOOL CGdiplusExt::GdipCreateFontFromFamily(void* pFamily, FX_FLOAT font_size, int fontstyle, int flag, void** pFont) -{ - CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - GpStatus status = CallFunc(GdipCreateFont)((GpFontFamily*)pFamily, font_size, fontstyle, Unit(flag), (GpFont**)pFont); - if (status == Ok) { - return TRUE; - } - return FALSE; +FX_BOOL CGdiplusExt::GdipCreateFontFromFamily(void* pFamily, + FX_FLOAT font_size, + int fontstyle, + int flag, + void** pFont) { + CGdiplusExt& GdiplusExt = + ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; + GpStatus status = + CallFunc(GdipCreateFont)((GpFontFamily*)pFamily, font_size, fontstyle, + Unit(flag), (GpFont**)pFont); + if (status == Ok) { + return TRUE; + } + return FALSE; } -void CGdiplusExt::GdipGetFontSize(void *pFont, FX_FLOAT *size) -{ - REAL get_size; - CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - GpStatus status = CallFunc(GdipGetFontSize)((GpFont *)pFont, (REAL*)&get_size); - if (status == Ok) { - *size = (FX_FLOAT)get_size; - } else { - *size = 0; - } +void CGdiplusExt::GdipGetFontSize(void* pFont, FX_FLOAT* size) { + REAL get_size; + CGdiplusExt& GdiplusExt = + ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; + GpStatus status = CallFunc(GdipGetFontSize)((GpFont*)pFont, (REAL*)&get_size); + if (status == Ok) { + *size = (FX_FLOAT)get_size; + } else { + *size = 0; + } } -void CGdiplusExt::GdipSetTextRenderingHint(void* graphics, int mode) -{ - CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - CallFunc(GdipSetTextRenderingHint)((GpGraphics*)graphics, (TextRenderingHint)mode); +void CGdiplusExt::GdipSetTextRenderingHint(void* graphics, int mode) { + CGdiplusExt& GdiplusExt = + ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; + CallFunc(GdipSetTextRenderingHint)((GpGraphics*)graphics, + (TextRenderingHint)mode); } -void CGdiplusExt::GdipSetPageUnit(void* graphics, FX_DWORD unit) -{ - CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - CallFunc(GdipSetPageUnit)((GpGraphics*)graphics, (GpUnit)unit); +void CGdiplusExt::GdipSetPageUnit(void* graphics, FX_DWORD unit) { + CGdiplusExt& GdiplusExt = + ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; + CallFunc(GdipSetPageUnit)((GpGraphics*)graphics, (GpUnit)unit); } -FX_BOOL CGdiplusExt::GdipDrawDriverString(void *graphics, unsigned short *text, int length, - void *font, void* brush, void *positions, int flags, const void *matrix) -{ - CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - GpStatus status = CallFunc(GdipDrawDriverString)((GpGraphics*)graphics, (GDIPCONST UINT16 *)text, (INT)length, (GDIPCONST GpFont *)font, (GDIPCONST GpBrush*)brush, - (GDIPCONST PointF *)positions, (INT)flags, (GDIPCONST GpMatrix *)matrix); - if (status == Ok) { - return TRUE; - } - return FALSE; +FX_BOOL CGdiplusExt::GdipDrawDriverString(void* graphics, + unsigned short* text, + int length, + void* font, + void* brush, + void* positions, + int flags, + const void* matrix) { + CGdiplusExt& GdiplusExt = + ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; + GpStatus status = CallFunc(GdipDrawDriverString)( + (GpGraphics*)graphics, (GDIPCONST UINT16*)text, (INT)length, + (GDIPCONST GpFont*)font, (GDIPCONST GpBrush*)brush, + (GDIPCONST PointF*)positions, (INT)flags, (GDIPCONST GpMatrix*)matrix); + if (status == Ok) { + return TRUE; + } + return FALSE; } -void CGdiplusExt::GdipCreateBrush(FX_DWORD fill_argb, void** pBrush) -{ - CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - CallFunc(GdipCreateSolidFill)((ARGB)fill_argb, (GpSolidFill**)pBrush); +void CGdiplusExt::GdipCreateBrush(FX_DWORD fill_argb, void** pBrush) { + CGdiplusExt& GdiplusExt = + ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; + CallFunc(GdipCreateSolidFill)((ARGB)fill_argb, (GpSolidFill**)pBrush); } -void CGdiplusExt::GdipDeleteBrush(void* pBrush) -{ - CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - CallFunc(GdipDeleteBrush)((GpSolidFill*)pBrush); +void CGdiplusExt::GdipDeleteBrush(void* pBrush) { + CGdiplusExt& GdiplusExt = + ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; + CallFunc(GdipDeleteBrush)((GpSolidFill*)pBrush); } -void* CGdiplusExt::GdipCreateFontFromCollection(void* pFontCollection, FX_FLOAT font_size, int fontstyle) -{ - CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - int numFamilies = 0; - GpStatus status = CallFunc(GdipGetFontCollectionFamilyCount)((GpFontCollection*)pFontCollection, &numFamilies); - if (status != Ok) { - return NULL; - } - GpFontFamily* family_list[1]; - status = CallFunc(GdipGetFontCollectionFamilyList)((GpFontCollection*)pFontCollection, 1, family_list, &numFamilies); - if (status != Ok) { - return NULL; - } - GpFont* pFont = NULL; - status = CallFunc(GdipCreateFont)(family_list[0], font_size, fontstyle, UnitPixel, &pFont); - if (status != Ok) { - return NULL; - } - return pFont; +void* CGdiplusExt::GdipCreateFontFromCollection(void* pFontCollection, + FX_FLOAT font_size, + int fontstyle) { + CGdiplusExt& GdiplusExt = + ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; + int numFamilies = 0; + GpStatus status = CallFunc(GdipGetFontCollectionFamilyCount)( + (GpFontCollection*)pFontCollection, &numFamilies); + if (status != Ok) { + return NULL; + } + GpFontFamily* family_list[1]; + status = CallFunc(GdipGetFontCollectionFamilyList)( + (GpFontCollection*)pFontCollection, 1, family_list, &numFamilies); + if (status != Ok) { + return NULL; + } + GpFont* pFont = NULL; + status = CallFunc(GdipCreateFont)(family_list[0], font_size, fontstyle, + UnitPixel, &pFont); + if (status != Ok) { + return NULL; + } + return pFont; } -void CGdiplusExt::GdipCreateMatrix(FX_FLOAT a, FX_FLOAT b, FX_FLOAT c, FX_FLOAT d, FX_FLOAT e, FX_FLOAT f, void** matrix) -{ - CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - CallFunc(GdipCreateMatrix2)(a, b, c, d, e, f, (GpMatrix**)matrix); +void CGdiplusExt::GdipCreateMatrix(FX_FLOAT a, + FX_FLOAT b, + FX_FLOAT c, + FX_FLOAT d, + FX_FLOAT e, + FX_FLOAT f, + void** matrix) { + CGdiplusExt& GdiplusExt = + ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; + CallFunc(GdipCreateMatrix2)(a, b, c, d, e, f, (GpMatrix**)matrix); } -void CGdiplusExt::GdipDeleteMatrix(void* matrix) -{ - CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - CallFunc(GdipDeleteMatrix)((GpMatrix*)matrix); +void CGdiplusExt::GdipDeleteMatrix(void* matrix) { + CGdiplusExt& GdiplusExt = + ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; + CallFunc(GdipDeleteMatrix)((GpMatrix*)matrix); } -void CGdiplusExt::GdipDeleteFontFamily(void* pFamily) -{ - CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - CallFunc(GdipDeleteFontFamily)((GpFontFamily*)pFamily); +void CGdiplusExt::GdipDeleteFontFamily(void* pFamily) { + CGdiplusExt& GdiplusExt = + ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; + CallFunc(GdipDeleteFontFamily)((GpFontFamily*)pFamily); } -void CGdiplusExt::GdipDeleteFont(void* pFont) -{ - CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - CallFunc(GdipDeleteFont)((GpFont*)pFont); +void CGdiplusExt::GdipDeleteFont(void* pFont) { + CGdiplusExt& GdiplusExt = + ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; + CallFunc(GdipDeleteFont)((GpFont*)pFont); } -void CGdiplusExt::GdipSetWorldTransform(void* graphics, void* pMatrix) -{ - CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - CallFunc(GdipSetWorldTransform)((GpGraphics*)graphics, (GpMatrix*)pMatrix); +void CGdiplusExt::GdipSetWorldTransform(void* graphics, void* pMatrix) { + CGdiplusExt& GdiplusExt = + ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; + CallFunc(GdipSetWorldTransform)((GpGraphics*)graphics, (GpMatrix*)pMatrix); } -void CGdiplusExt::GdipDisposeImage(void* bitmap) -{ - CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - CallFunc(GdipDisposeImage)((GpBitmap*)bitmap); +void CGdiplusExt::GdipDisposeImage(void* bitmap) { + CGdiplusExt& GdiplusExt = + ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; + CallFunc(GdipDisposeImage)((GpBitmap*)bitmap); } -void CGdiplusExt::GdipDeleteGraphics(void* graphics) -{ - CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - CallFunc(GdipDeleteGraphics)((GpGraphics*)graphics); +void CGdiplusExt::GdipDeleteGraphics(void* graphics) { + CGdiplusExt& GdiplusExt = + ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; + CallFunc(GdipDeleteGraphics)((GpGraphics*)graphics); } -FX_BOOL CGdiplusExt::StretchBitMask(HDC hDC, BOOL bMonoDevice, const CFX_DIBitmap* pBitmap, int dest_left, int dest_top, - int dest_width, int dest_height, FX_DWORD argb, const FX_RECT* pClipRect, int flags) -{ - ASSERT(pBitmap->GetBPP() == 1); - CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - GpGraphics* pGraphics = NULL; - CallFunc(GdipCreateFromHDC)(hDC, &pGraphics); - CallFunc(GdipSetPageUnit)(pGraphics, UnitPixel); - if (flags & FXDIB_NOSMOOTH) { - CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeNearestNeighbor); - } else { - CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeHighQuality); - } - OutputImageMask(pGraphics, bMonoDevice, pBitmap, dest_left, dest_top, dest_width, dest_height, argb, pClipRect); - CallFunc(GdipDeleteGraphics)(pGraphics); - return TRUE; +FX_BOOL CGdiplusExt::StretchBitMask(HDC hDC, + BOOL bMonoDevice, + const CFX_DIBitmap* pBitmap, + int dest_left, + int dest_top, + int dest_width, + int dest_height, + FX_DWORD argb, + const FX_RECT* pClipRect, + int flags) { + ASSERT(pBitmap->GetBPP() == 1); + CGdiplusExt& GdiplusExt = + ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; + GpGraphics* pGraphics = NULL; + CallFunc(GdipCreateFromHDC)(hDC, &pGraphics); + CallFunc(GdipSetPageUnit)(pGraphics, UnitPixel); + if (flags & FXDIB_NOSMOOTH) { + CallFunc(GdipSetInterpolationMode)(pGraphics, + InterpolationModeNearestNeighbor); + } else { + CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeHighQuality); + } + OutputImageMask(pGraphics, bMonoDevice, pBitmap, dest_left, dest_top, + dest_width, dest_height, argb, pClipRect); + CallFunc(GdipDeleteGraphics)(pGraphics); + return TRUE; } -FX_BOOL CGdiplusExt::StretchDIBits(HDC hDC, const CFX_DIBitmap* pBitmap, int dest_left, int dest_top, - int dest_width, int dest_height, const FX_RECT* pClipRect, int flags) -{ - GpGraphics* pGraphics; - CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - CallFunc(GdipCreateFromHDC)(hDC, &pGraphics); - CallFunc(GdipSetPageUnit)(pGraphics, UnitPixel); - if (flags & FXDIB_NOSMOOTH) { - CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeNearestNeighbor); - } else if (pBitmap->GetWidth() > abs(dest_width) / 2 || pBitmap->GetHeight() > abs(dest_height) / 2) { - CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeHighQuality); - } else { - CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeBilinear); - } - FX_RECT src_rect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight()); - OutputImage(pGraphics, pBitmap, &src_rect, dest_left, dest_top, dest_width, dest_height); - CallFunc(GdipDeleteGraphics)(pGraphics); - CallFunc(GdipDeleteGraphics)(pGraphics); - return TRUE; +FX_BOOL CGdiplusExt::StretchDIBits(HDC hDC, + const CFX_DIBitmap* pBitmap, + int dest_left, + int dest_top, + int dest_width, + int dest_height, + const FX_RECT* pClipRect, + int flags) { + GpGraphics* pGraphics; + CGdiplusExt& GdiplusExt = + ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; + CallFunc(GdipCreateFromHDC)(hDC, &pGraphics); + CallFunc(GdipSetPageUnit)(pGraphics, UnitPixel); + if (flags & FXDIB_NOSMOOTH) { + CallFunc(GdipSetInterpolationMode)(pGraphics, + InterpolationModeNearestNeighbor); + } else if (pBitmap->GetWidth() > abs(dest_width) / 2 || + pBitmap->GetHeight() > abs(dest_height) / 2) { + CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeHighQuality); + } else { + CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeBilinear); + } + FX_RECT src_rect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight()); + OutputImage(pGraphics, pBitmap, &src_rect, dest_left, dest_top, dest_width, + dest_height); + CallFunc(GdipDeleteGraphics)(pGraphics); + CallFunc(GdipDeleteGraphics)(pGraphics); + return TRUE; } -static GpPen* _GdipCreatePen(const CFX_GraphStateData* pGraphState, const CFX_AffineMatrix* pMatrix, DWORD argb, FX_BOOL bTextMode = FALSE) -{ - CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - FX_FLOAT width = pGraphState ? pGraphState->m_LineWidth : 1.0f; - if (!bTextMode) { - FX_FLOAT unit = pMatrix == NULL ? 1.0f : FXSYS_Div(1.0f, (pMatrix->GetXUnit() + pMatrix->GetYUnit()) / 2); - if (width < unit) { - width = unit; - } - } - GpPen* pPen = NULL; - CallFunc(GdipCreatePen1)((ARGB)argb, width, UnitWorld, &pPen); - LineCap lineCap; - DashCap dashCap = DashCapFlat; - FX_BOOL bDashExtend = FALSE; - switch(pGraphState->m_LineCap) { - case CFX_GraphStateData::LineCapButt: - lineCap = LineCapFlat; - break; - case CFX_GraphStateData::LineCapRound: - lineCap = LineCapRound; - dashCap = DashCapRound; - bDashExtend = TRUE; - break; - case CFX_GraphStateData::LineCapSquare: - lineCap = LineCapSquare; - bDashExtend = TRUE; - break; - } - CallFunc(GdipSetPenLineCap197819)(pPen, lineCap, lineCap, dashCap); - LineJoin lineJoin; - switch(pGraphState->m_LineJoin) { - case CFX_GraphStateData::LineJoinMiter: - lineJoin = LineJoinMiterClipped; - break; - case CFX_GraphStateData::LineJoinRound: - lineJoin = LineJoinRound; - break; - case CFX_GraphStateData::LineJoinBevel: - lineJoin = LineJoinBevel; - break; - } - CallFunc(GdipSetPenLineJoin)(pPen, lineJoin); - if(pGraphState->m_DashCount) { - FX_FLOAT* pDashArray = FX_Alloc(FX_FLOAT, pGraphState->m_DashCount + pGraphState->m_DashCount % 2); - int nCount = 0; - FX_FLOAT on_leftover = 0, off_leftover = 0; - for (int i = 0; i < pGraphState->m_DashCount; i += 2) { - FX_FLOAT on_phase = pGraphState->m_DashArray[i]; - FX_FLOAT off_phase; - if (i == pGraphState->m_DashCount - 1) { - off_phase = on_phase; - } else { - off_phase = pGraphState->m_DashArray[i + 1]; - } - on_phase /= width; - off_phase /= width; - if (on_phase + off_phase <= 0.00002f) { - on_phase = 1.0f / 10; - off_phase = 1.0f / 10; - } - if (bDashExtend) { - if (off_phase < 1) { - off_phase = 0; - } else { - off_phase -= 1; - } - on_phase += 1; - } - if (on_phase == 0 || off_phase == 0) { - if (nCount == 0) { - on_leftover += on_phase; - off_leftover += off_phase; - } else { - pDashArray[nCount - 2] += on_phase; - pDashArray[nCount - 1] += off_phase; - } - } else { - pDashArray[nCount++] = on_phase + on_leftover; - on_leftover = 0; - pDashArray[nCount++] = off_phase + off_leftover; - off_leftover = 0; - } +static GpPen* _GdipCreatePen(const CFX_GraphStateData* pGraphState, + const CFX_AffineMatrix* pMatrix, + DWORD argb, + FX_BOOL bTextMode = FALSE) { + CGdiplusExt& GdiplusExt = + ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; + FX_FLOAT width = pGraphState ? pGraphState->m_LineWidth : 1.0f; + if (!bTextMode) { + FX_FLOAT unit = + pMatrix == NULL + ? 1.0f + : FXSYS_Div(1.0f, (pMatrix->GetXUnit() + pMatrix->GetYUnit()) / 2); + if (width < unit) { + width = unit; + } + } + GpPen* pPen = NULL; + CallFunc(GdipCreatePen1)((ARGB)argb, width, UnitWorld, &pPen); + LineCap lineCap; + DashCap dashCap = DashCapFlat; + FX_BOOL bDashExtend = FALSE; + switch (pGraphState->m_LineCap) { + case CFX_GraphStateData::LineCapButt: + lineCap = LineCapFlat; + break; + case CFX_GraphStateData::LineCapRound: + lineCap = LineCapRound; + dashCap = DashCapRound; + bDashExtend = TRUE; + break; + case CFX_GraphStateData::LineCapSquare: + lineCap = LineCapSquare; + bDashExtend = TRUE; + break; + } + CallFunc(GdipSetPenLineCap197819)(pPen, lineCap, lineCap, dashCap); + LineJoin lineJoin; + switch (pGraphState->m_LineJoin) { + case CFX_GraphStateData::LineJoinMiter: + lineJoin = LineJoinMiterClipped; + break; + case CFX_GraphStateData::LineJoinRound: + lineJoin = LineJoinRound; + break; + case CFX_GraphStateData::LineJoinBevel: + lineJoin = LineJoinBevel; + break; + } + CallFunc(GdipSetPenLineJoin)(pPen, lineJoin); + if (pGraphState->m_DashCount) { + FX_FLOAT* pDashArray = FX_Alloc( + FX_FLOAT, pGraphState->m_DashCount + pGraphState->m_DashCount % 2); + int nCount = 0; + FX_FLOAT on_leftover = 0, off_leftover = 0; + for (int i = 0; i < pGraphState->m_DashCount; i += 2) { + FX_FLOAT on_phase = pGraphState->m_DashArray[i]; + FX_FLOAT off_phase; + if (i == pGraphState->m_DashCount - 1) { + off_phase = on_phase; + } else { + off_phase = pGraphState->m_DashArray[i + 1]; + } + on_phase /= width; + off_phase /= width; + if (on_phase + off_phase <= 0.00002f) { + on_phase = 1.0f / 10; + off_phase = 1.0f / 10; + } + if (bDashExtend) { + if (off_phase < 1) { + off_phase = 0; + } else { + off_phase -= 1; } - CallFunc(GdipSetPenDashArray)(pPen, pDashArray, nCount); - FX_FLOAT phase = pGraphState->m_DashPhase; - if (bDashExtend) { - if (phase < 0.5f) { - phase = 0; - } else { - phase -= 0.5f; - } + on_phase += 1; + } + if (on_phase == 0 || off_phase == 0) { + if (nCount == 0) { + on_leftover += on_phase; + off_leftover += off_phase; + } else { + pDashArray[nCount - 2] += on_phase; + pDashArray[nCount - 1] += off_phase; } - CallFunc(GdipSetPenDashOffset)(pPen, phase); - FX_Free(pDashArray); - pDashArray = NULL; - } - CallFunc(GdipSetPenMiterLimit)(pPen, pGraphState->m_MiterLimit); - return pPen; + } else { + pDashArray[nCount++] = on_phase + on_leftover; + on_leftover = 0; + pDashArray[nCount++] = off_phase + off_leftover; + off_leftover = 0; + } + } + CallFunc(GdipSetPenDashArray)(pPen, pDashArray, nCount); + FX_FLOAT phase = pGraphState->m_DashPhase; + if (bDashExtend) { + if (phase < 0.5f) { + phase = 0; + } else { + phase -= 0.5f; + } + } + CallFunc(GdipSetPenDashOffset)(pPen, phase); + FX_Free(pDashArray); + pDashArray = NULL; + } + CallFunc(GdipSetPenMiterLimit)(pPen, pGraphState->m_MiterLimit); + return pPen; } -static FX_BOOL IsSmallTriangle(PointF* points, const CFX_AffineMatrix* pMatrix, int& v1, int& v2) -{ - int pairs[] = {1, 2, 0, 2, 0, 1}; - for (int i = 0; i < 3; i ++) { - int pair1 = pairs[i * 2]; - int pair2 = pairs[i * 2 + 1]; - FX_FLOAT x1 = points[pair1].X, x2 = points[pair2].X; - FX_FLOAT y1 = points[pair1].Y, y2 = points[pair2].Y; - if (pMatrix) { - pMatrix->Transform(x1, y1); - pMatrix->Transform(x2, y2); - } - FX_FLOAT dx = x1 - x2; - FX_FLOAT dy = y1 - y2; - FX_FLOAT distance_square = FXSYS_Mul(dx, dx) + FXSYS_Mul(dy, dy); - if (distance_square < (1.0f * 2 + 1.0f / 4)) { - v1 = i; - v2 = pair1; - return TRUE; - } - } - return FALSE; +static FX_BOOL IsSmallTriangle(PointF* points, + const CFX_AffineMatrix* pMatrix, + int& v1, + int& v2) { + int pairs[] = {1, 2, 0, 2, 0, 1}; + for (int i = 0; i < 3; i++) { + int pair1 = pairs[i * 2]; + int pair2 = pairs[i * 2 + 1]; + FX_FLOAT x1 = points[pair1].X, x2 = points[pair2].X; + FX_FLOAT y1 = points[pair1].Y, y2 = points[pair2].Y; + if (pMatrix) { + pMatrix->Transform(x1, y1); + pMatrix->Transform(x2, y2); + } + FX_FLOAT dx = x1 - x2; + FX_FLOAT dy = y1 - y2; + FX_FLOAT distance_square = FXSYS_Mul(dx, dx) + FXSYS_Mul(dy, dy); + if (distance_square < (1.0f * 2 + 1.0f / 4)) { + v1 = i; + v2 = pair1; + return TRUE; + } + } + return FALSE; } -FX_BOOL CGdiplusExt::DrawPath(HDC hDC, const CFX_PathData* pPathData, - const CFX_AffineMatrix* pObject2Device, - const CFX_GraphStateData* pGraphState, - FX_DWORD fill_argb, - FX_DWORD stroke_argb, - int fill_mode - ) -{ - int nPoints = pPathData->GetPointCount(); - if (nPoints == 0) { - return TRUE; - } - FX_PATHPOINT* pPoints = pPathData->GetPoints(); - GpGraphics* pGraphics = NULL; - CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - CallFunc(GdipCreateFromHDC)(hDC, &pGraphics); - CallFunc(GdipSetPageUnit)(pGraphics, UnitPixel); - CallFunc(GdipSetPixelOffsetMode)(pGraphics, PixelOffsetModeHalf); - GpMatrix* pMatrix = NULL; +FX_BOOL CGdiplusExt::DrawPath(HDC hDC, + const CFX_PathData* pPathData, + const CFX_AffineMatrix* pObject2Device, + const CFX_GraphStateData* pGraphState, + FX_DWORD fill_argb, + FX_DWORD stroke_argb, + int fill_mode) { + int nPoints = pPathData->GetPointCount(); + if (nPoints == 0) { + return TRUE; + } + FX_PATHPOINT* pPoints = pPathData->GetPoints(); + GpGraphics* pGraphics = NULL; + CGdiplusExt& GdiplusExt = + ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; + CallFunc(GdipCreateFromHDC)(hDC, &pGraphics); + CallFunc(GdipSetPageUnit)(pGraphics, UnitPixel); + CallFunc(GdipSetPixelOffsetMode)(pGraphics, PixelOffsetModeHalf); + GpMatrix* pMatrix = NULL; + if (pObject2Device) { + CallFunc(GdipCreateMatrix2)(pObject2Device->a, pObject2Device->b, + pObject2Device->c, pObject2Device->d, + pObject2Device->e, pObject2Device->f, &pMatrix); + CallFunc(GdipSetWorldTransform)(pGraphics, pMatrix); + } + PointF* points = FX_Alloc(PointF, nPoints); + BYTE* types = FX_Alloc(BYTE, nPoints); + int nSubPathes = 0; + FX_BOOL bSubClose = FALSE; + int pos_subclose = 0; + FX_BOOL bSmooth = FALSE; + int startpoint = 0; + for (int i = 0; i < nPoints; i++) { + points[i].X = pPoints[i].m_PointX; + points[i].Y = pPoints[i].m_PointY; + FX_FLOAT x, y; if (pObject2Device) { - CallFunc(GdipCreateMatrix2)(pObject2Device->a, pObject2Device->b, pObject2Device->c, pObject2Device->d, pObject2Device->e, pObject2Device->f, &pMatrix); - CallFunc(GdipSetWorldTransform)(pGraphics, pMatrix); - } - PointF *points = FX_Alloc(PointF, nPoints); - BYTE * types = FX_Alloc(BYTE, nPoints); - int nSubPathes = 0; - FX_BOOL bSubClose = FALSE; - int pos_subclose = 0; - FX_BOOL bSmooth = FALSE; - int startpoint = 0; - for(int i = 0; i < nPoints; i++) { - points[i].X = pPoints[i].m_PointX; - points[i].Y = pPoints[i].m_PointY; - FX_FLOAT x, y; - if (pObject2Device) { - pObject2Device->Transform(pPoints[i].m_PointX, pPoints[i].m_PointY, x, y); - } else { - x = pPoints[i].m_PointX; - y = pPoints[i].m_PointY; - } - if (x > 50000 * 1.0f) { - points[i].X = 50000 * 1.0f; - } - if (x < -50000 * 1.0f) { - points[i].X = -50000 * 1.0f; - } - if (y > 50000 * 1.0f) { - points[i].Y = 50000 * 1.0f; - } - if (y < -50000 * 1.0f) { - points[i].Y = -50000 * 1.0f; - } - int point_type = pPoints[i].m_Flag & FXPT_TYPE; - if(point_type == FXPT_MOVETO) { - types[i] = PathPointTypeStart; - nSubPathes ++; - bSubClose = FALSE; - startpoint = i; - } else if (point_type == FXPT_LINETO) { - types[i] = PathPointTypeLine; - if (pPoints[i - 1].m_Flag == FXPT_MOVETO && (i == nPoints - 1 || pPoints[i + 1].m_Flag == FXPT_MOVETO) && - points[i].Y == points[i - 1].Y && points[i].X == points[i - 1].X) { - points[i].X += 0.01f; - continue; - } - if (!bSmooth && points[i].X != points[i - 1].X && points[i].Y != points[i - 1].Y) { - bSmooth = TRUE; - } - } else if (point_type == FXPT_BEZIERTO) { - types[i] = PathPointTypeBezier; - bSmooth = TRUE; - } - if (pPoints[i].m_Flag & FXPT_CLOSEFIGURE) { - if (bSubClose) { - types[pos_subclose] &= ~PathPointTypeCloseSubpath; - } else { - bSubClose = TRUE; - } - pos_subclose = i; - types[i] |= PathPointTypeCloseSubpath; - if (!bSmooth && points[i].X != points[startpoint].X && points[i].Y != points[startpoint].Y) { - bSmooth = TRUE; - } - } - } - if (fill_mode & FXFILL_NOPATHSMOOTH) { - bSmooth = FALSE; - CallFunc(GdipSetSmoothingMode)(pGraphics, SmoothingModeNone); - } else if (!(fill_mode & FXFILL_FULLCOVER)) { - if (!bSmooth && (fill_mode & 3)) { - bSmooth = TRUE; - } - if (bSmooth || (pGraphState && pGraphState->m_LineWidth > 2)) { - CallFunc(GdipSetSmoothingMode)(pGraphics, SmoothingModeAntiAlias); - } - } - int new_fill_mode = fill_mode & 3; - if (nPoints == 4 && pGraphState == NULL) { - int v1, v2; - if (IsSmallTriangle(points, pObject2Device, v1, v2)) { - GpPen* pPen = NULL; - CallFunc(GdipCreatePen1)(fill_argb, 1.0f, UnitPixel, &pPen); - CallFunc(GdipDrawLineI)(pGraphics, pPen, FXSYS_round(points[v1].X), FXSYS_round(points[v1].Y), - FXSYS_round(points[v2].X), FXSYS_round(points[v2].Y)); - CallFunc(GdipDeletePen)(pPen); - return TRUE; - } - } - GpPath* pGpPath = NULL; - CallFunc(GdipCreatePath2)(points, types, nPoints, GdiFillType2Gdip(new_fill_mode), &pGpPath); - if (!pGpPath) { - if (pMatrix) { - CallFunc(GdipDeleteMatrix)(pMatrix); - } - FX_Free(points); - FX_Free(types); - CallFunc(GdipDeleteGraphics)(pGraphics); - return FALSE; - } - if (new_fill_mode) { - GpBrush* pBrush = _GdipCreateBrush(fill_argb); - CallFunc(GdipSetPathFillMode)(pGpPath, GdiFillType2Gdip(new_fill_mode)); - CallFunc(GdipFillPath)(pGraphics, pBrush, pGpPath); - CallFunc(GdipDeleteBrush)(pBrush); - } - if (pGraphState && stroke_argb) { - GpPen* pPen = _GdipCreatePen(pGraphState, pObject2Device, stroke_argb, fill_mode & FX_STROKE_TEXT_MODE); - if (nSubPathes == 1) { - CallFunc(GdipDrawPath)(pGraphics, pPen, pGpPath); - } else { - int iStart = 0; - for (int i = 0; i < nPoints; i ++) { - if (i == nPoints - 1 || types[i + 1] == PathPointTypeStart) { - GpPath* pSubPath; - CallFunc(GdipCreatePath2)(points + iStart, types + iStart, i - iStart + 1, GdiFillType2Gdip(new_fill_mode), &pSubPath); - iStart = i + 1; - CallFunc(GdipDrawPath)(pGraphics, pPen, pSubPath); - CallFunc(GdipDeletePath)(pSubPath); - } - } - } - CallFunc(GdipDeletePen)(pPen); - } + pObject2Device->Transform(pPoints[i].m_PointX, pPoints[i].m_PointY, x, y); + } else { + x = pPoints[i].m_PointX; + y = pPoints[i].m_PointY; + } + if (x > 50000 * 1.0f) { + points[i].X = 50000 * 1.0f; + } + if (x < -50000 * 1.0f) { + points[i].X = -50000 * 1.0f; + } + if (y > 50000 * 1.0f) { + points[i].Y = 50000 * 1.0f; + } + if (y < -50000 * 1.0f) { + points[i].Y = -50000 * 1.0f; + } + int point_type = pPoints[i].m_Flag & FXPT_TYPE; + if (point_type == FXPT_MOVETO) { + types[i] = PathPointTypeStart; + nSubPathes++; + bSubClose = FALSE; + startpoint = i; + } else if (point_type == FXPT_LINETO) { + types[i] = PathPointTypeLine; + if (pPoints[i - 1].m_Flag == FXPT_MOVETO && + (i == nPoints - 1 || pPoints[i + 1].m_Flag == FXPT_MOVETO) && + points[i].Y == points[i - 1].Y && points[i].X == points[i - 1].X) { + points[i].X += 0.01f; + continue; + } + if (!bSmooth && points[i].X != points[i - 1].X && + points[i].Y != points[i - 1].Y) { + bSmooth = TRUE; + } + } else if (point_type == FXPT_BEZIERTO) { + types[i] = PathPointTypeBezier; + bSmooth = TRUE; + } + if (pPoints[i].m_Flag & FXPT_CLOSEFIGURE) { + if (bSubClose) { + types[pos_subclose] &= ~PathPointTypeCloseSubpath; + } else { + bSubClose = TRUE; + } + pos_subclose = i; + types[i] |= PathPointTypeCloseSubpath; + if (!bSmooth && points[i].X != points[startpoint].X && + points[i].Y != points[startpoint].Y) { + bSmooth = TRUE; + } + } + } + if (fill_mode & FXFILL_NOPATHSMOOTH) { + bSmooth = FALSE; + CallFunc(GdipSetSmoothingMode)(pGraphics, SmoothingModeNone); + } else if (!(fill_mode & FXFILL_FULLCOVER)) { + if (!bSmooth && (fill_mode & 3)) { + bSmooth = TRUE; + } + if (bSmooth || (pGraphState && pGraphState->m_LineWidth > 2)) { + CallFunc(GdipSetSmoothingMode)(pGraphics, SmoothingModeAntiAlias); + } + } + int new_fill_mode = fill_mode & 3; + if (nPoints == 4 && pGraphState == NULL) { + int v1, v2; + if (IsSmallTriangle(points, pObject2Device, v1, v2)) { + GpPen* pPen = NULL; + CallFunc(GdipCreatePen1)(fill_argb, 1.0f, UnitPixel, &pPen); + CallFunc(GdipDrawLineI)( + pGraphics, pPen, FXSYS_round(points[v1].X), FXSYS_round(points[v1].Y), + FXSYS_round(points[v2].X), FXSYS_round(points[v2].Y)); + CallFunc(GdipDeletePen)(pPen); + return TRUE; + } + } + GpPath* pGpPath = NULL; + CallFunc(GdipCreatePath2)(points, types, nPoints, + GdiFillType2Gdip(new_fill_mode), &pGpPath); + if (!pGpPath) { if (pMatrix) { - CallFunc(GdipDeleteMatrix)(pMatrix); + CallFunc(GdipDeleteMatrix)(pMatrix); } FX_Free(points); FX_Free(types); - CallFunc(GdipDeletePath)(pGpPath); CallFunc(GdipDeleteGraphics)(pGraphics); - return TRUE; -} -class GpStream final : public IStream -{ - LONG m_RefCount; - int m_ReadPos; - CFX_ByteTextBuf m_InterStream; -public: - GpStream() - { - m_RefCount = 1; - m_ReadPos = 0; - } - virtual HRESULT STDMETHODCALLTYPE - QueryInterface(REFIID iid, void ** ppvObject) - { - if (iid == __uuidof(IUnknown) || - iid == __uuidof(IStream) || - iid == __uuidof(ISequentialStream)) { - *ppvObject = static_cast(this); - AddRef(); - return S_OK; - } - return E_NOINTERFACE; - } - virtual ULONG STDMETHODCALLTYPE AddRef(void) - { - return (ULONG)InterlockedIncrement(&m_RefCount); - } - virtual ULONG STDMETHODCALLTYPE Release(void) - { - ULONG res = (ULONG) InterlockedDecrement(&m_RefCount); - if (res == 0) { - delete this; - } - return res; - } -public: - virtual HRESULT STDMETHODCALLTYPE Read(void* Output, ULONG cb, ULONG* pcbRead) - { - size_t bytes_left; - size_t bytes_out; - if (pcbRead != NULL) { - *pcbRead = 0; - } - if (m_ReadPos == m_InterStream.GetLength()) { - return HRESULT_FROM_WIN32(ERROR_END_OF_MEDIA); - } - bytes_left = m_InterStream.GetLength() - m_ReadPos; - bytes_out = FX_MIN(cb, bytes_left); - FXSYS_memcpy(Output, m_InterStream.GetBuffer() + m_ReadPos, bytes_out); - m_ReadPos += (int32_t)bytes_out; - if (pcbRead != NULL) { - *pcbRead = (ULONG)bytes_out; - } - return S_OK; - } - virtual HRESULT STDMETHODCALLTYPE Write(void const* Input, ULONG cb, ULONG* pcbWritten) - { - if (cb <= 0) { - if (pcbWritten != NULL) { - *pcbWritten = 0; - } - return S_OK; - } - m_InterStream.InsertBlock(m_InterStream.GetLength(), Input, cb); - if (pcbWritten != NULL) { - *pcbWritten = cb; - } - return S_OK; - } -public: - virtual HRESULT STDMETHODCALLTYPE SetSize(ULARGE_INTEGER) - { - return E_NOTIMPL; - } - virtual HRESULT STDMETHODCALLTYPE CopyTo(IStream*, ULARGE_INTEGER, ULARGE_INTEGER*, ULARGE_INTEGER*) - { - return E_NOTIMPL; - } - virtual HRESULT STDMETHODCALLTYPE Commit(DWORD) - { - return E_NOTIMPL; - } - virtual HRESULT STDMETHODCALLTYPE Revert(void) - { - return E_NOTIMPL; - } - virtual HRESULT STDMETHODCALLTYPE LockRegion(ULARGE_INTEGER, ULARGE_INTEGER, DWORD) - { - return E_NOTIMPL; - } - virtual HRESULT STDMETHODCALLTYPE UnlockRegion(ULARGE_INTEGER, ULARGE_INTEGER, DWORD) - { - return E_NOTIMPL; - } - virtual HRESULT STDMETHODCALLTYPE Clone(IStream **) - { - return E_NOTIMPL; - } - virtual HRESULT STDMETHODCALLTYPE Seek(LARGE_INTEGER liDistanceToMove, DWORD dwOrigin, ULARGE_INTEGER* lpNewFilePointer) - { - long start = 0; - long new_read_position; - switch(dwOrigin) { - case STREAM_SEEK_SET: - start = 0; - break; - case STREAM_SEEK_CUR: - start = m_ReadPos; - break; - case STREAM_SEEK_END: - start = m_InterStream.GetLength(); - break; - default: - return STG_E_INVALIDFUNCTION; - break; - } - new_read_position = start + (long)liDistanceToMove.QuadPart; - if (new_read_position < 0 || new_read_position > m_InterStream.GetLength()) { - return STG_E_SEEKERROR; - } - m_ReadPos = new_read_position; - if (lpNewFilePointer != NULL) { - lpNewFilePointer->QuadPart = m_ReadPos; - } - return S_OK; - } - virtual HRESULT STDMETHODCALLTYPE Stat(STATSTG* pStatstg, DWORD grfStatFlag) - { - if (pStatstg == NULL) { - return STG_E_INVALIDFUNCTION; + return FALSE; + } + if (new_fill_mode) { + GpBrush* pBrush = _GdipCreateBrush(fill_argb); + CallFunc(GdipSetPathFillMode)(pGpPath, GdiFillType2Gdip(new_fill_mode)); + CallFunc(GdipFillPath)(pGraphics, pBrush, pGpPath); + CallFunc(GdipDeleteBrush)(pBrush); + } + if (pGraphState && stroke_argb) { + GpPen* pPen = _GdipCreatePen(pGraphState, pObject2Device, stroke_argb, + fill_mode & FX_STROKE_TEXT_MODE); + if (nSubPathes == 1) { + CallFunc(GdipDrawPath)(pGraphics, pPen, pGpPath); + } else { + int iStart = 0; + for (int i = 0; i < nPoints; i++) { + if (i == nPoints - 1 || types[i + 1] == PathPointTypeStart) { + GpPath* pSubPath; + CallFunc(GdipCreatePath2)(points + iStart, types + iStart, + i - iStart + 1, + GdiFillType2Gdip(new_fill_mode), &pSubPath); + iStart = i + 1; + CallFunc(GdipDrawPath)(pGraphics, pPen, pSubPath); + CallFunc(GdipDeletePath)(pSubPath); } - ZeroMemory(pStatstg, sizeof(STATSTG)); - pStatstg->cbSize.QuadPart = m_InterStream.GetLength(); - return S_OK; - } + } + } + CallFunc(GdipDeletePen)(pPen); + } + if (pMatrix) { + CallFunc(GdipDeleteMatrix)(pMatrix); + } + FX_Free(points); + FX_Free(types); + CallFunc(GdipDeletePath)(pGpPath); + CallFunc(GdipDeleteGraphics)(pGraphics); + return TRUE; +} +class GpStream final : public IStream { + LONG m_RefCount; + int m_ReadPos; + CFX_ByteTextBuf m_InterStream; + + public: + GpStream() { + m_RefCount = 1; + m_ReadPos = 0; + } + virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, + void** ppvObject) { + if (iid == __uuidof(IUnknown) || iid == __uuidof(IStream) || + iid == __uuidof(ISequentialStream)) { + *ppvObject = static_cast(this); + AddRef(); + return S_OK; + } + return E_NOINTERFACE; + } + virtual ULONG STDMETHODCALLTYPE AddRef(void) { + return (ULONG)InterlockedIncrement(&m_RefCount); + } + virtual ULONG STDMETHODCALLTYPE Release(void) { + ULONG res = (ULONG)InterlockedDecrement(&m_RefCount); + if (res == 0) { + delete this; + } + return res; + } + + public: + virtual HRESULT STDMETHODCALLTYPE Read(void* Output, + ULONG cb, + ULONG* pcbRead) { + size_t bytes_left; + size_t bytes_out; + if (pcbRead != NULL) { + *pcbRead = 0; + } + if (m_ReadPos == m_InterStream.GetLength()) { + return HRESULT_FROM_WIN32(ERROR_END_OF_MEDIA); + } + bytes_left = m_InterStream.GetLength() - m_ReadPos; + bytes_out = FX_MIN(cb, bytes_left); + FXSYS_memcpy(Output, m_InterStream.GetBuffer() + m_ReadPos, bytes_out); + m_ReadPos += (int32_t)bytes_out; + if (pcbRead != NULL) { + *pcbRead = (ULONG)bytes_out; + } + return S_OK; + } + virtual HRESULT STDMETHODCALLTYPE Write(void const* Input, + ULONG cb, + ULONG* pcbWritten) { + if (cb <= 0) { + if (pcbWritten != NULL) { + *pcbWritten = 0; + } + return S_OK; + } + m_InterStream.InsertBlock(m_InterStream.GetLength(), Input, cb); + if (pcbWritten != NULL) { + *pcbWritten = cb; + } + return S_OK; + } + + public: + virtual HRESULT STDMETHODCALLTYPE SetSize(ULARGE_INTEGER) { + return E_NOTIMPL; + } + virtual HRESULT STDMETHODCALLTYPE CopyTo(IStream*, + ULARGE_INTEGER, + ULARGE_INTEGER*, + ULARGE_INTEGER*) { + return E_NOTIMPL; + } + virtual HRESULT STDMETHODCALLTYPE Commit(DWORD) { return E_NOTIMPL; } + virtual HRESULT STDMETHODCALLTYPE Revert(void) { return E_NOTIMPL; } + virtual HRESULT STDMETHODCALLTYPE LockRegion(ULARGE_INTEGER, + ULARGE_INTEGER, + DWORD) { + return E_NOTIMPL; + } + virtual HRESULT STDMETHODCALLTYPE UnlockRegion(ULARGE_INTEGER, + ULARGE_INTEGER, + DWORD) { + return E_NOTIMPL; + } + virtual HRESULT STDMETHODCALLTYPE Clone(IStream**) { return E_NOTIMPL; } + virtual HRESULT STDMETHODCALLTYPE Seek(LARGE_INTEGER liDistanceToMove, + DWORD dwOrigin, + ULARGE_INTEGER* lpNewFilePointer) { + long start = 0; + long new_read_position; + switch (dwOrigin) { + case STREAM_SEEK_SET: + start = 0; + break; + case STREAM_SEEK_CUR: + start = m_ReadPos; + break; + case STREAM_SEEK_END: + start = m_InterStream.GetLength(); + break; + default: + return STG_E_INVALIDFUNCTION; + break; + } + new_read_position = start + (long)liDistanceToMove.QuadPart; + if (new_read_position < 0 || + new_read_position > m_InterStream.GetLength()) { + return STG_E_SEEKERROR; + } + m_ReadPos = new_read_position; + if (lpNewFilePointer != NULL) { + lpNewFilePointer->QuadPart = m_ReadPos; + } + return S_OK; + } + virtual HRESULT STDMETHODCALLTYPE Stat(STATSTG* pStatstg, DWORD grfStatFlag) { + if (pStatstg == NULL) { + return STG_E_INVALIDFUNCTION; + } + ZeroMemory(pStatstg, sizeof(STATSTG)); + pStatstg->cbSize.QuadPart = m_InterStream.GetLength(); + return S_OK; + } }; typedef struct { - BITMAPINFO* pbmi; - int Stride; - LPBYTE pScan0; - GpBitmap* pBitmap; - BitmapData* pBitmapData; - GpStream* pStream; + BITMAPINFO* pbmi; + int Stride; + LPBYTE pScan0; + GpBitmap* pBitmap; + BitmapData* pBitmapData; + GpStream* pStream; } PREVIEW3_DIBITMAP; -static PREVIEW3_DIBITMAP* LoadDIBitmap(WINDIB_Open_Args_ args) -{ - GpBitmap* pBitmap; - GpStream* pStream = NULL; - CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - Status status = Ok; - if (args.flags == WINDIB_OPEN_PATHNAME) { - status = CallFunc(GdipCreateBitmapFromFileICM)((wchar_t*)args.path_name, &pBitmap); - } else { - if (args.memory_size == 0 || !args.memory_base) { - return NULL; - } - pStream = new GpStream; - pStream->Write(args.memory_base, (ULONG)args.memory_size, NULL); - status = CallFunc(GdipCreateBitmapFromStreamICM)(pStream, &pBitmap); - } - if (status != Ok) { - if (pStream) { - pStream->Release(); - } - return NULL; - } - UINT height, width; - CallFunc(GdipGetImageHeight)(pBitmap, &height); - CallFunc(GdipGetImageWidth)(pBitmap, &width); - PixelFormat pixel_format; - CallFunc(GdipGetImagePixelFormat)(pBitmap, &pixel_format); - int info_size = sizeof(BITMAPINFOHEADER); - int bpp = 24; - int dest_pixel_format = PixelFormat24bppRGB; - if (pixel_format == PixelFormat1bppIndexed) { - info_size += 8; - bpp = 1; - dest_pixel_format = PixelFormat1bppIndexed; - } else if (pixel_format == PixelFormat8bppIndexed) { - info_size += 1024; - bpp = 8; - dest_pixel_format = PixelFormat8bppIndexed; - } else if (pixel_format == PixelFormat32bppARGB) { - bpp = 32; - dest_pixel_format = PixelFormat32bppARGB; +static PREVIEW3_DIBITMAP* LoadDIBitmap(WINDIB_Open_Args_ args) { + GpBitmap* pBitmap; + GpStream* pStream = NULL; + CGdiplusExt& GdiplusExt = + ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; + Status status = Ok; + if (args.flags == WINDIB_OPEN_PATHNAME) { + status = CallFunc(GdipCreateBitmapFromFileICM)((wchar_t*)args.path_name, + &pBitmap); + } else { + if (args.memory_size == 0 || !args.memory_base) { + return NULL; + } + pStream = new GpStream; + pStream->Write(args.memory_base, (ULONG)args.memory_size, NULL); + status = CallFunc(GdipCreateBitmapFromStreamICM)(pStream, &pBitmap); + } + if (status != Ok) { + if (pStream) { + pStream->Release(); } - LPBYTE buf = FX_Alloc(BYTE, info_size); - BITMAPINFOHEADER* pbmih = (BITMAPINFOHEADER*)buf; - pbmih->biBitCount = bpp; - pbmih->biCompression = BI_RGB; - pbmih->biHeight = -(int)height; - pbmih->biPlanes = 1; - pbmih->biWidth = width; - Rect rect(0, 0, width, height); - BitmapData* pBitmapData = FX_Alloc(BitmapData, 1); - CallFunc(GdipBitmapLockBits)(pBitmap, &rect, ImageLockModeRead, - dest_pixel_format, pBitmapData); - if (pixel_format == PixelFormat1bppIndexed || pixel_format == PixelFormat8bppIndexed) { - DWORD* ppal = (DWORD*)(buf + sizeof(BITMAPINFOHEADER)); - struct { - UINT flags; - UINT Count; - DWORD Entries[256]; - } pal; - int size = 0; - CallFunc(GdipGetImagePaletteSize)(pBitmap, &size); - CallFunc(GdipGetImagePalette)(pBitmap, (ColorPalette*)&pal, size); - int entries = pixel_format == PixelFormat1bppIndexed ? 2 : 256; - for (int i = 0; i < entries; i ++) { - ppal[i] = pal.Entries[i] & 0x00ffffff; - } - } - PREVIEW3_DIBITMAP* pInfo = FX_Alloc(PREVIEW3_DIBITMAP, 1); - pInfo->pbmi = (BITMAPINFO*)buf; - pInfo->pScan0 = (LPBYTE)pBitmapData->Scan0; - pInfo->Stride = pBitmapData->Stride; - pInfo->pBitmap = pBitmap; - pInfo->pBitmapData = pBitmapData; - pInfo->pStream = pStream; - return pInfo; + return NULL; + } + UINT height, width; + CallFunc(GdipGetImageHeight)(pBitmap, &height); + CallFunc(GdipGetImageWidth)(pBitmap, &width); + PixelFormat pixel_format; + CallFunc(GdipGetImagePixelFormat)(pBitmap, &pixel_format); + int info_size = sizeof(BITMAPINFOHEADER); + int bpp = 24; + int dest_pixel_format = PixelFormat24bppRGB; + if (pixel_format == PixelFormat1bppIndexed) { + info_size += 8; + bpp = 1; + dest_pixel_format = PixelFormat1bppIndexed; + } else if (pixel_format == PixelFormat8bppIndexed) { + info_size += 1024; + bpp = 8; + dest_pixel_format = PixelFormat8bppIndexed; + } else if (pixel_format == PixelFormat32bppARGB) { + bpp = 32; + dest_pixel_format = PixelFormat32bppARGB; + } + LPBYTE buf = FX_Alloc(BYTE, info_size); + BITMAPINFOHEADER* pbmih = (BITMAPINFOHEADER*)buf; + pbmih->biBitCount = bpp; + pbmih->biCompression = BI_RGB; + pbmih->biHeight = -(int)height; + pbmih->biPlanes = 1; + pbmih->biWidth = width; + Rect rect(0, 0, width, height); + BitmapData* pBitmapData = FX_Alloc(BitmapData, 1); + CallFunc(GdipBitmapLockBits)(pBitmap, &rect, ImageLockModeRead, + dest_pixel_format, pBitmapData); + if (pixel_format == PixelFormat1bppIndexed || + pixel_format == PixelFormat8bppIndexed) { + DWORD* ppal = (DWORD*)(buf + sizeof(BITMAPINFOHEADER)); + struct { + UINT flags; + UINT Count; + DWORD Entries[256]; + } pal; + int size = 0; + CallFunc(GdipGetImagePaletteSize)(pBitmap, &size); + CallFunc(GdipGetImagePalette)(pBitmap, (ColorPalette*)&pal, size); + int entries = pixel_format == PixelFormat1bppIndexed ? 2 : 256; + for (int i = 0; i < entries; i++) { + ppal[i] = pal.Entries[i] & 0x00ffffff; + } + } + PREVIEW3_DIBITMAP* pInfo = FX_Alloc(PREVIEW3_DIBITMAP, 1); + pInfo->pbmi = (BITMAPINFO*)buf; + pInfo->pScan0 = (LPBYTE)pBitmapData->Scan0; + pInfo->Stride = pBitmapData->Stride; + pInfo->pBitmap = pBitmap; + pInfo->pBitmapData = pBitmapData; + pInfo->pStream = pStream; + return pInfo; } -static void FreeDIBitmap(PREVIEW3_DIBITMAP* pInfo) -{ - CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; - CallFunc(GdipBitmapUnlockBits)(pInfo->pBitmap, pInfo->pBitmapData); - CallFunc(GdipDisposeImage)(pInfo->pBitmap); - FX_Free(pInfo->pBitmapData); - FX_Free((LPBYTE)pInfo->pbmi); - if (pInfo->pStream) { - pInfo->pStream->Release(); - } - FX_Free(pInfo); +static void FreeDIBitmap(PREVIEW3_DIBITMAP* pInfo) { + CGdiplusExt& GdiplusExt = + ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; + CallFunc(GdipBitmapUnlockBits)(pInfo->pBitmap, pInfo->pBitmapData); + CallFunc(GdipDisposeImage)(pInfo->pBitmap); + FX_Free(pInfo->pBitmapData); + FX_Free((LPBYTE)pInfo->pbmi); + if (pInfo->pStream) { + pInfo->pStream->Release(); + } + FX_Free(pInfo); } -CFX_DIBitmap* _FX_WindowsDIB_LoadFromBuf(BITMAPINFO* pbmi, LPVOID pData, FX_BOOL bAlpha); -CFX_DIBitmap* CGdiplusExt::LoadDIBitmap(WINDIB_Open_Args_ args) -{ - PREVIEW3_DIBITMAP* pInfo = ::LoadDIBitmap(args); - if (pInfo == NULL) { - return NULL; - } - int height = abs(pInfo->pbmi->bmiHeader.biHeight); - int width = pInfo->pbmi->bmiHeader.biWidth; - int dest_pitch = (width * pInfo->pbmi->bmiHeader.biBitCount + 31) / 32 * 4; - LPBYTE pData = FX_Alloc2D(BYTE, dest_pitch, height); - if (dest_pitch == pInfo->Stride) { - FXSYS_memcpy(pData, pInfo->pScan0, dest_pitch * height); - } else { - for (int i = 0; i < height; i ++) { - FXSYS_memcpy(pData + dest_pitch * i, pInfo->pScan0 + pInfo->Stride * i, dest_pitch); - } - } - CFX_DIBitmap* pDIBitmap = _FX_WindowsDIB_LoadFromBuf(pInfo->pbmi, pData, pInfo->pbmi->bmiHeader.biBitCount == 32); - FX_Free(pData); - FreeDIBitmap(pInfo); - return pDIBitmap; +CFX_DIBitmap* _FX_WindowsDIB_LoadFromBuf(BITMAPINFO* pbmi, + LPVOID pData, + FX_BOOL bAlpha); +CFX_DIBitmap* CGdiplusExt::LoadDIBitmap(WINDIB_Open_Args_ args) { + PREVIEW3_DIBITMAP* pInfo = ::LoadDIBitmap(args); + if (pInfo == NULL) { + return NULL; + } + int height = abs(pInfo->pbmi->bmiHeader.biHeight); + int width = pInfo->pbmi->bmiHeader.biWidth; + int dest_pitch = (width * pInfo->pbmi->bmiHeader.biBitCount + 31) / 32 * 4; + LPBYTE pData = FX_Alloc2D(BYTE, dest_pitch, height); + if (dest_pitch == pInfo->Stride) { + FXSYS_memcpy(pData, pInfo->pScan0, dest_pitch * height); + } else { + for (int i = 0; i < height; i++) { + FXSYS_memcpy(pData + dest_pitch * i, pInfo->pScan0 + pInfo->Stride * i, + dest_pitch); + } + } + CFX_DIBitmap* pDIBitmap = _FX_WindowsDIB_LoadFromBuf( + pInfo->pbmi, pData, pInfo->pbmi->bmiHeader.biBitCount == 32); + FX_Free(pData); + FreeDIBitmap(pInfo); + return pDIBitmap; } #endif diff --git a/core/src/fxge/win32/fx_win32_print.cpp b/core/src/fxge/win32/fx_win32_print.cpp index 86dbf9bb0a..85f339b529 100644 --- a/core/src/fxge/win32/fx_win32_print.cpp +++ b/core/src/fxge/win32/fx_win32_print.cpp @@ -14,397 +14,464 @@ #include "../dib/dib_int.h" #define SIZETHRESHOLD 1000 #define OUTPUTPSLEN 4096 -CGdiPrinterDriver::CGdiPrinterDriver(HDC hDC) : CGdiDeviceDriver(hDC, FXDC_PRINTER) -{ - m_HorzSize = ::GetDeviceCaps(m_hDC, HORZSIZE); - m_VertSize = ::GetDeviceCaps(m_hDC, VERTSIZE); - m_bSupportROP = TRUE; +CGdiPrinterDriver::CGdiPrinterDriver(HDC hDC) + : CGdiDeviceDriver(hDC, FXDC_PRINTER) { + m_HorzSize = ::GetDeviceCaps(m_hDC, HORZSIZE); + m_VertSize = ::GetDeviceCaps(m_hDC, VERTSIZE); + m_bSupportROP = TRUE; } -int CGdiPrinterDriver::GetDeviceCaps(int caps_id) -{ - if (caps_id == FXDC_HORZ_SIZE) { - return m_HorzSize; - } - if (caps_id == FXDC_VERT_SIZE) { - return m_VertSize; - } - return CGdiDeviceDriver::GetDeviceCaps(caps_id); +int CGdiPrinterDriver::GetDeviceCaps(int caps_id) { + if (caps_id == FXDC_HORZ_SIZE) { + return m_HorzSize; + } + if (caps_id == FXDC_VERT_SIZE) { + return m_VertSize; + } + return CGdiDeviceDriver::GetDeviceCaps(caps_id); +} +FX_BOOL CGdiPrinterDriver::SetDIBits(const CFX_DIBSource* pSource, + FX_DWORD color, + const FX_RECT* pSrcRect, + int left, + int top, + int blend_type, + int alpha_flag, + void* pIccTransform) { + if (pSource->IsAlphaMask()) { + FX_RECT clip_rect(left, top, left + pSrcRect->Width(), + top + pSrcRect->Height()); + return StretchDIBits(pSource, color, left - pSrcRect->left, + top - pSrcRect->top, pSource->GetWidth(), + pSource->GetHeight(), &clip_rect, 0, alpha_flag, + pIccTransform, FXDIB_BLEND_NORMAL); + } + ASSERT(pSource != NULL && !pSource->IsAlphaMask() && pSrcRect != NULL); + ASSERT(blend_type == FXDIB_BLEND_NORMAL); + if (pSource->HasAlpha()) { + return FALSE; + } + CFX_DIBExtractor temp(pSource); + CFX_DIBitmap* pBitmap = temp; + if (pBitmap == NULL) { + return FALSE; + } + return GDI_SetDIBits(pBitmap, pSrcRect, left, top, pIccTransform); } -FX_BOOL CGdiPrinterDriver::SetDIBits(const CFX_DIBSource* pSource, FX_DWORD color, const FX_RECT* pSrcRect, int left, int top, int blend_type, - int alpha_flag, void* pIccTransform) -{ - if (pSource->IsAlphaMask()) { - FX_RECT clip_rect(left, top, left + pSrcRect->Width(), top + pSrcRect->Height()); - return StretchDIBits(pSource, color, left - pSrcRect->left, top - pSrcRect->top, pSource->GetWidth(), pSource->GetHeight(), - &clip_rect, 0, alpha_flag, pIccTransform, FXDIB_BLEND_NORMAL); +FX_BOOL CGdiPrinterDriver::StretchDIBits(const CFX_DIBSource* pSource, + FX_DWORD color, + int dest_left, + int dest_top, + int dest_width, + int dest_height, + const FX_RECT* pClipRect, + FX_DWORD flags, + int alpha_flag, + void* pIccTransform, + int blend_type) { + if (pSource->IsAlphaMask()) { + int alpha = FXGETFLAG_COLORTYPE(alpha_flag) + ? FXGETFLAG_ALPHA_FILL(alpha_flag) + : FXARGB_A(color); + if (pSource->GetBPP() != 1 || alpha != 255 || !m_bSupportROP) { + return FALSE; } - ASSERT(pSource != NULL && !pSource->IsAlphaMask() && pSrcRect != NULL); - ASSERT(blend_type == FXDIB_BLEND_NORMAL); - if (pSource->HasAlpha()) { + if (dest_width < 0 || dest_height < 0) { + CFX_DIBitmap* pFlipped = + pSource->FlipImage(dest_width < 0, dest_height < 0); + if (pFlipped == NULL) { return FALSE; + } + if (dest_width < 0) { + dest_left += dest_width; + } + if (dest_height < 0) { + dest_top += dest_height; + } + FX_BOOL ret = GDI_StretchBitMask(pFlipped, dest_left, dest_top, + abs(dest_width), abs(dest_height), color, + flags, alpha_flag, pIccTransform); + delete pFlipped; + return ret; } CFX_DIBExtractor temp(pSource); CFX_DIBitmap* pBitmap = temp; if (pBitmap == NULL) { - return FALSE; + return FALSE; } - return GDI_SetDIBits(pBitmap, pSrcRect, left, top, pIccTransform); -} -FX_BOOL CGdiPrinterDriver::StretchDIBits(const CFX_DIBSource* pSource, FX_DWORD color, int dest_left, int dest_top, - int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags, - int alpha_flag, void* pIccTransform, int blend_type) -{ - if (pSource->IsAlphaMask()) { - int alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(color); - if (pSource->GetBPP() != 1 || alpha != 255 || !m_bSupportROP) { - return FALSE; - } - if (dest_width < 0 || dest_height < 0) { - CFX_DIBitmap* pFlipped = pSource->FlipImage(dest_width < 0, dest_height < 0); - if (pFlipped == NULL) { - return FALSE; - } - if (dest_width < 0) { - dest_left += dest_width; - } - if (dest_height < 0) { - dest_top += dest_height; - } - FX_BOOL ret = GDI_StretchBitMask(pFlipped, dest_left, dest_top, abs(dest_width), abs(dest_height), color, flags, alpha_flag, pIccTransform); - delete pFlipped; - return ret; - } - CFX_DIBExtractor temp(pSource); - CFX_DIBitmap* pBitmap = temp; - if (pBitmap == NULL) { - return FALSE; - } - return GDI_StretchBitMask(pBitmap, dest_left, dest_top, dest_width, dest_height, color, flags, alpha_flag, pIccTransform); + return GDI_StretchBitMask(pBitmap, dest_left, dest_top, dest_width, + dest_height, color, flags, alpha_flag, + pIccTransform); + } + if (pSource->HasAlpha()) { + return FALSE; + } + if (dest_width < 0 || dest_height < 0) { + CFX_DIBitmap* pFlipped = + pSource->FlipImage(dest_width < 0, dest_height < 0); + if (pFlipped == NULL) { + return FALSE; } - if (pSource->HasAlpha()) { - return FALSE; + if (dest_width < 0) { + dest_left += dest_width; } - if (dest_width < 0 || dest_height < 0) { - CFX_DIBitmap* pFlipped = pSource->FlipImage(dest_width < 0, dest_height < 0); - if (pFlipped == NULL) { - return FALSE; - } - if (dest_width < 0) { - dest_left += dest_width; - } - if (dest_height < 0) { - dest_top += dest_height; - } - FX_BOOL ret = GDI_StretchDIBits(pFlipped, dest_left, dest_top, abs(dest_width), abs(dest_height), flags, pIccTransform); - delete pFlipped; - return ret; - } - CFX_DIBExtractor temp(pSource); - CFX_DIBitmap* pBitmap = temp; - if (pBitmap == NULL) { - return FALSE; + if (dest_height < 0) { + dest_top += dest_height; } - return GDI_StretchDIBits(pBitmap, dest_left, dest_top, dest_width, dest_height, flags, pIccTransform); + FX_BOOL ret = + GDI_StretchDIBits(pFlipped, dest_left, dest_top, abs(dest_width), + abs(dest_height), flags, pIccTransform); + delete pFlipped; + return ret; + } + CFX_DIBExtractor temp(pSource); + CFX_DIBitmap* pBitmap = temp; + if (pBitmap == NULL) { + return FALSE; + } + return GDI_StretchDIBits(pBitmap, dest_left, dest_top, dest_width, + dest_height, flags, pIccTransform); } -static CFX_DIBitmap* Transform1bppBitmap(const CFX_DIBSource* pSrc, const CFX_AffineMatrix* pDestMatrix) -{ - ASSERT(pSrc->GetFormat() == FXDIB_1bppRgb || pSrc->GetFormat() == FXDIB_1bppMask || pSrc->GetFormat() == FXDIB_1bppCmyk); - CFX_FloatRect unit_rect = pDestMatrix->GetUnitRect(); - FX_RECT full_rect = unit_rect.GetOutterRect(); - int full_left = full_rect.left; - int full_top = full_rect.top; - CFX_DIBExtractor src_bitmap(pSrc); - CFX_DIBitmap* pSrcBitmap = src_bitmap; - if (pSrcBitmap == NULL) { - return NULL; +static CFX_DIBitmap* Transform1bppBitmap(const CFX_DIBSource* pSrc, + const CFX_AffineMatrix* pDestMatrix) { + ASSERT(pSrc->GetFormat() == FXDIB_1bppRgb || + pSrc->GetFormat() == FXDIB_1bppMask || + pSrc->GetFormat() == FXDIB_1bppCmyk); + CFX_FloatRect unit_rect = pDestMatrix->GetUnitRect(); + FX_RECT full_rect = unit_rect.GetOutterRect(); + int full_left = full_rect.left; + int full_top = full_rect.top; + CFX_DIBExtractor src_bitmap(pSrc); + CFX_DIBitmap* pSrcBitmap = src_bitmap; + if (pSrcBitmap == NULL) { + return NULL; + } + int src_width = pSrcBitmap->GetWidth(), src_height = pSrcBitmap->GetHeight(); + uint8_t* src_buf = pSrcBitmap->GetBuffer(); + FX_DWORD src_pitch = pSrcBitmap->GetPitch(); + FX_FLOAT dest_area = pDestMatrix->GetUnitArea(); + FX_FLOAT area_scale = + FXSYS_Div((FX_FLOAT)(src_width * src_height), dest_area); + FX_FLOAT size_scale = FXSYS_sqrt(area_scale); + CFX_AffineMatrix adjusted_matrix(*pDestMatrix); + adjusted_matrix.Scale(size_scale, size_scale); + CFX_FloatRect result_rect_f = adjusted_matrix.GetUnitRect(); + FX_RECT result_rect = result_rect_f.GetOutterRect(); + CFX_AffineMatrix src2result; + src2result.e = adjusted_matrix.c + adjusted_matrix.e; + src2result.f = adjusted_matrix.d + adjusted_matrix.f; + src2result.a = adjusted_matrix.a / pSrcBitmap->GetWidth(); + src2result.b = adjusted_matrix.b / pSrcBitmap->GetWidth(); + src2result.c = -adjusted_matrix.c / pSrcBitmap->GetHeight(); + src2result.d = -adjusted_matrix.d / pSrcBitmap->GetHeight(); + src2result.TranslateI(-result_rect.left, -result_rect.top); + CFX_AffineMatrix result2src; + result2src.SetReverse(src2result); + CPDF_FixedMatrix result2src_fix(result2src, 8); + int result_width = result_rect.Width(); + int result_height = result_rect.Height(); + CFX_DIBitmap* pTempBitmap = new CFX_DIBitmap; + if (!pTempBitmap->Create(result_width, result_height, pSrc->GetFormat())) { + delete pTempBitmap; + if (pSrcBitmap != src_bitmap) { + delete pSrcBitmap; } - int src_width = pSrcBitmap->GetWidth(), src_height = pSrcBitmap->GetHeight(); - uint8_t* src_buf = pSrcBitmap->GetBuffer(); - FX_DWORD src_pitch = pSrcBitmap->GetPitch(); - FX_FLOAT dest_area = pDestMatrix->GetUnitArea(); - FX_FLOAT area_scale = FXSYS_Div((FX_FLOAT)(src_width * src_height), dest_area); - FX_FLOAT size_scale = FXSYS_sqrt(area_scale); - CFX_AffineMatrix adjusted_matrix(*pDestMatrix); - adjusted_matrix.Scale(size_scale, size_scale); - CFX_FloatRect result_rect_f = adjusted_matrix.GetUnitRect(); - FX_RECT result_rect = result_rect_f.GetOutterRect(); - CFX_AffineMatrix src2result; - src2result.e = adjusted_matrix.c + adjusted_matrix.e; - src2result.f = adjusted_matrix.d + adjusted_matrix.f; - src2result.a = adjusted_matrix.a / pSrcBitmap->GetWidth(); - src2result.b = adjusted_matrix.b / pSrcBitmap->GetWidth(); - src2result.c = -adjusted_matrix.c / pSrcBitmap->GetHeight(); - src2result.d = -adjusted_matrix.d / pSrcBitmap->GetHeight(); - src2result.TranslateI(-result_rect.left, -result_rect.top); - CFX_AffineMatrix result2src; - result2src.SetReverse(src2result); - CPDF_FixedMatrix result2src_fix(result2src, 8); - int result_width = result_rect.Width(); - int result_height = result_rect.Height(); - CFX_DIBitmap* pTempBitmap = new CFX_DIBitmap; - if (!pTempBitmap->Create(result_width, result_height, pSrc->GetFormat())) { - delete pTempBitmap; - if (pSrcBitmap != src_bitmap) { - delete pSrcBitmap; + return NULL; + } + pTempBitmap->CopyPalette(pSrc->GetPalette()); + uint8_t* dest_buf = pTempBitmap->GetBuffer(); + int dest_pitch = pTempBitmap->GetPitch(); + FXSYS_memset(dest_buf, pSrc->IsAlphaMask() ? 0 : 0xff, + dest_pitch * result_height); + if (pSrcBitmap->IsAlphaMask()) { + for (int dest_y = 0; dest_y < result_height; dest_y++) { + uint8_t* dest_scan = dest_buf + dest_y * dest_pitch; + for (int dest_x = 0; dest_x < result_width; dest_x++) { + int src_x, src_y; + result2src_fix.Transform(dest_x, dest_y, src_x, src_y); + if (src_x < 0 || src_x >= src_width || src_y < 0 || + src_y >= src_height) { + continue; } - return NULL; + if (!((src_buf + src_pitch * src_y)[src_x / 8] & + (1 << (7 - src_x % 8)))) { + continue; + } + dest_scan[dest_x / 8] |= 1 << (7 - dest_x % 8); + } } - pTempBitmap->CopyPalette(pSrc->GetPalette()); - uint8_t* dest_buf = pTempBitmap->GetBuffer(); - int dest_pitch = pTempBitmap->GetPitch(); - FXSYS_memset(dest_buf, pSrc->IsAlphaMask() ? 0 : 0xff, dest_pitch * result_height); - if (pSrcBitmap->IsAlphaMask()) { - for (int dest_y = 0; dest_y < result_height; dest_y ++) { - uint8_t* dest_scan = dest_buf + dest_y * dest_pitch; - for (int dest_x = 0; dest_x < result_width; dest_x ++) { - int src_x, src_y; - result2src_fix.Transform(dest_x, dest_y, src_x, src_y); - if (src_x < 0 || src_x >= src_width || src_y < 0 || src_y >= src_height) { - continue; - } - if (!((src_buf + src_pitch * src_y)[src_x / 8] & (1 << (7 - src_x % 8)))) { - continue; - } - dest_scan[dest_x / 8] |= 1 << (7 - dest_x % 8); - } + } else { + for (int dest_y = 0; dest_y < result_height; dest_y++) { + uint8_t* dest_scan = dest_buf + dest_y * dest_pitch; + for (int dest_x = 0; dest_x < result_width; dest_x++) { + int src_x, src_y; + result2src_fix.Transform(dest_x, dest_y, src_x, src_y); + if (src_x < 0 || src_x >= src_width || src_y < 0 || + src_y >= src_height) { + continue; } - } else { - for (int dest_y = 0; dest_y < result_height; dest_y ++) { - uint8_t* dest_scan = dest_buf + dest_y * dest_pitch; - for (int dest_x = 0; dest_x < result_width; dest_x ++) { - int src_x, src_y; - result2src_fix.Transform(dest_x, dest_y, src_x, src_y); - if (src_x < 0 || src_x >= src_width || src_y < 0 || src_y >= src_height) { - continue; - } - if ((src_buf + src_pitch * src_y)[src_x / 8] & (1 << (7 - src_x % 8))) { - continue; - } - dest_scan[dest_x / 8] &= ~(1 << (7 - dest_x % 8)); - } + if ((src_buf + src_pitch * src_y)[src_x / 8] & (1 << (7 - src_x % 8))) { + continue; } + dest_scan[dest_x / 8] &= ~(1 << (7 - dest_x % 8)); + } } - if (pSrcBitmap != src_bitmap) { - delete pSrcBitmap; - } - return pTempBitmap; + } + if (pSrcBitmap != src_bitmap) { + delete pSrcBitmap; + } + return pTempBitmap; } -FX_BOOL CGdiPrinterDriver::StartDIBits(const CFX_DIBSource* pSource, int bitmap_alpha, FX_DWORD color, - const CFX_AffineMatrix* pMatrix, FX_DWORD render_flags, void*& handle, - int alpha_flag, void* pIccTransform, int blend_type) -{ - if (bitmap_alpha < 255 || pSource->HasAlpha() || (pSource->IsAlphaMask() && (pSource->GetBPP() != 1 || !m_bSupportROP))) { - return FALSE; - } - CFX_FloatRect unit_rect = pMatrix->GetUnitRect(); - FX_RECT full_rect = unit_rect.GetOutterRect(); - if (FXSYS_fabs(pMatrix->b) < 0.5f && pMatrix->a != 0 && FXSYS_fabs(pMatrix->c) < 0.5f && pMatrix->d != 0) { - FX_BOOL bFlipX = pMatrix->a < 0; - FX_BOOL bFlipY = pMatrix->d > 0; - return StretchDIBits(pSource, color, bFlipX ? full_rect.right : full_rect.left, bFlipY ? full_rect.bottom : full_rect.top, - bFlipX ? -full_rect.Width() : full_rect.Width(), bFlipY ? -full_rect.Height() : full_rect.Height(), NULL, 0, - alpha_flag, pIccTransform, blend_type); +FX_BOOL CGdiPrinterDriver::StartDIBits(const CFX_DIBSource* pSource, + int bitmap_alpha, + FX_DWORD color, + const CFX_AffineMatrix* pMatrix, + FX_DWORD render_flags, + void*& handle, + int alpha_flag, + void* pIccTransform, + int blend_type) { + if (bitmap_alpha < 255 || pSource->HasAlpha() || + (pSource->IsAlphaMask() && (pSource->GetBPP() != 1 || !m_bSupportROP))) { + return FALSE; + } + CFX_FloatRect unit_rect = pMatrix->GetUnitRect(); + FX_RECT full_rect = unit_rect.GetOutterRect(); + if (FXSYS_fabs(pMatrix->b) < 0.5f && pMatrix->a != 0 && + FXSYS_fabs(pMatrix->c) < 0.5f && pMatrix->d != 0) { + FX_BOOL bFlipX = pMatrix->a < 0; + FX_BOOL bFlipY = pMatrix->d > 0; + return StretchDIBits(pSource, color, + bFlipX ? full_rect.right : full_rect.left, + bFlipY ? full_rect.bottom : full_rect.top, + bFlipX ? -full_rect.Width() : full_rect.Width(), + bFlipY ? -full_rect.Height() : full_rect.Height(), + NULL, 0, alpha_flag, pIccTransform, blend_type); + } + if (FXSYS_fabs(pMatrix->a) < 0.5f && FXSYS_fabs(pMatrix->d) < 0.5f) { + CFX_DIBitmap* pTransformed = + pSource->SwapXY(pMatrix->c > 0, pMatrix->b < 0); + if (pTransformed == NULL) { + return FALSE; } - if (FXSYS_fabs(pMatrix->a) < 0.5f && FXSYS_fabs(pMatrix->d) < 0.5f) { - CFX_DIBitmap* pTransformed = pSource->SwapXY(pMatrix->c > 0, pMatrix->b < 0); - if (pTransformed == NULL) { - return FALSE; - } - FX_BOOL ret = StretchDIBits(pTransformed, color, full_rect.left, full_rect.top, full_rect.Width(), full_rect.Height(), NULL, 0, - alpha_flag, pIccTransform, blend_type); - delete pTransformed; - return ret; + FX_BOOL ret = StretchDIBits( + pTransformed, color, full_rect.left, full_rect.top, full_rect.Width(), + full_rect.Height(), NULL, 0, alpha_flag, pIccTransform, blend_type); + delete pTransformed; + return ret; + } + if (pSource->GetBPP() == 1) { + CFX_DIBitmap* pTransformed = Transform1bppBitmap(pSource, pMatrix); + if (pIccTransform == NULL) { + return FALSE; } - if (pSource->GetBPP() == 1) { - CFX_DIBitmap* pTransformed = Transform1bppBitmap(pSource, pMatrix); - if (pIccTransform == NULL) { - return FALSE; - } - SaveState(); - CFX_PathData path; - path.AppendRect(0, 0, 1.0f, 1.0f); - SetClip_PathFill(&path, pMatrix, WINDING); - FX_BOOL ret = StretchDIBits(pTransformed, color, full_rect.left, full_rect.top, full_rect.Width(), full_rect.Height(), NULL, 0, - alpha_flag, pIccTransform, blend_type); - RestoreState(); - delete pTransformed; - handle = NULL; - return ret; - } - return FALSE; + SaveState(); + CFX_PathData path; + path.AppendRect(0, 0, 1.0f, 1.0f); + SetClip_PathFill(&path, pMatrix, WINDING); + FX_BOOL ret = StretchDIBits( + pTransformed, color, full_rect.left, full_rect.top, full_rect.Width(), + full_rect.Height(), NULL, 0, alpha_flag, pIccTransform, blend_type); + RestoreState(); + delete pTransformed; + handle = NULL; + return ret; + } + return FALSE; } -CPSOutput::CPSOutput(HDC hDC) -{ - m_hDC = hDC; - m_pBuf = NULL; +CPSOutput::CPSOutput(HDC hDC) { + m_hDC = hDC; + m_pBuf = NULL; } -CPSOutput::~CPSOutput() -{ - if (m_pBuf) { - FX_Free(m_pBuf); - } +CPSOutput::~CPSOutput() { + if (m_pBuf) { + FX_Free(m_pBuf); + } } -void CPSOutput::Init() -{ - m_pBuf = FX_Alloc(FX_CHAR, 1026); +void CPSOutput::Init() { + m_pBuf = FX_Alloc(FX_CHAR, 1026); } -void CPSOutput::OutputPS(const FX_CHAR* string, int len) -{ - if (len < 0) { - len = (int)FXSYS_strlen(string); - } - int sent_len = 0; - while (len > 0) { - int send_len = len > 1024 ? 1024 : len; - *(FX_WORD*)m_pBuf = send_len; - FXSYS_memcpy(m_pBuf + 2, string + sent_len, send_len); - int ret = ExtEscape(m_hDC, PASSTHROUGH, send_len + 2, m_pBuf, 0, NULL); - sent_len += send_len; - len -= send_len; - } +void CPSOutput::OutputPS(const FX_CHAR* string, int len) { + if (len < 0) { + len = (int)FXSYS_strlen(string); + } + int sent_len = 0; + while (len > 0) { + int send_len = len > 1024 ? 1024 : len; + *(FX_WORD*)m_pBuf = send_len; + FXSYS_memcpy(m_pBuf + 2, string + sent_len, send_len); + int ret = ExtEscape(m_hDC, PASSTHROUGH, send_len + 2, m_pBuf, 0, NULL); + sent_len += send_len; + len -= send_len; + } } -CPSPrinterDriver::CPSPrinterDriver() -{ - m_pPSOutput = NULL; - m_bCmykOutput = FALSE; +CPSPrinterDriver::CPSPrinterDriver() { + m_pPSOutput = NULL; + m_bCmykOutput = FALSE; } -CPSPrinterDriver::~CPSPrinterDriver() -{ - EndRendering(); - delete m_pPSOutput; +CPSPrinterDriver::~CPSPrinterDriver() { + EndRendering(); + delete m_pPSOutput; } -FX_BOOL CPSPrinterDriver::Init(HDC hDC, int pslevel, FX_BOOL bCmykOutput) -{ - m_hDC = hDC; - m_HorzSize = ::GetDeviceCaps(m_hDC, HORZSIZE); - m_VertSize = ::GetDeviceCaps(m_hDC, VERTSIZE); - m_Width = ::GetDeviceCaps(m_hDC, HORZRES); - m_Height = ::GetDeviceCaps(m_hDC, VERTRES); - m_nBitsPerPixel = ::GetDeviceCaps(m_hDC, BITSPIXEL); - m_pPSOutput = new CPSOutput(hDC); - ((CPSOutput*)m_pPSOutput)->Init(); - m_PSRenderer.Init(m_pPSOutput, pslevel, m_Width, m_Height, bCmykOutput); - m_bCmykOutput = bCmykOutput; - HRGN hRgn = ::CreateRectRgn(0, 0, 1, 1); - int ret = ::GetClipRgn(hDC, hRgn); - if (ret == 1) { - ret = ::GetRegionData(hRgn, 0, NULL); - if (ret) { - RGNDATA* pData = (RGNDATA*)FX_Alloc(uint8_t, ret); - ret = ::GetRegionData(hRgn, ret, pData); - if (ret) { - CFX_PathData path; - path.AllocPointCount(pData->rdh.nCount * 5); - for (FX_DWORD i = 0; i < pData->rdh.nCount; i ++) { - RECT* pRect = (RECT*)(pData->Buffer + pData->rdh.nRgnSize * i); - path.AppendRect((FX_FLOAT)pRect->left, (FX_FLOAT)pRect->bottom, (FX_FLOAT)pRect->right, (FX_FLOAT)pRect->top); - } - m_PSRenderer.SetClip_PathFill(&path, NULL, FXFILL_WINDING); - } - FX_Free(pData); +FX_BOOL CPSPrinterDriver::Init(HDC hDC, int pslevel, FX_BOOL bCmykOutput) { + m_hDC = hDC; + m_HorzSize = ::GetDeviceCaps(m_hDC, HORZSIZE); + m_VertSize = ::GetDeviceCaps(m_hDC, VERTSIZE); + m_Width = ::GetDeviceCaps(m_hDC, HORZRES); + m_Height = ::GetDeviceCaps(m_hDC, VERTRES); + m_nBitsPerPixel = ::GetDeviceCaps(m_hDC, BITSPIXEL); + m_pPSOutput = new CPSOutput(hDC); + ((CPSOutput*)m_pPSOutput)->Init(); + m_PSRenderer.Init(m_pPSOutput, pslevel, m_Width, m_Height, bCmykOutput); + m_bCmykOutput = bCmykOutput; + HRGN hRgn = ::CreateRectRgn(0, 0, 1, 1); + int ret = ::GetClipRgn(hDC, hRgn); + if (ret == 1) { + ret = ::GetRegionData(hRgn, 0, NULL); + if (ret) { + RGNDATA* pData = (RGNDATA*)FX_Alloc(uint8_t, ret); + ret = ::GetRegionData(hRgn, ret, pData); + if (ret) { + CFX_PathData path; + path.AllocPointCount(pData->rdh.nCount * 5); + for (FX_DWORD i = 0; i < pData->rdh.nCount; i++) { + RECT* pRect = (RECT*)(pData->Buffer + pData->rdh.nRgnSize * i); + path.AppendRect((FX_FLOAT)pRect->left, (FX_FLOAT)pRect->bottom, + (FX_FLOAT)pRect->right, (FX_FLOAT)pRect->top); } + m_PSRenderer.SetClip_PathFill(&path, NULL, FXFILL_WINDING); + } + FX_Free(pData); } - ::DeleteObject(hRgn); - return TRUE; + } + ::DeleteObject(hRgn); + return TRUE; } -int CPSPrinterDriver::GetDeviceCaps(int caps_id) -{ - switch (caps_id) { - case FXDC_DEVICE_CLASS: - return FXDC_PRINTER; - case FXDC_PIXEL_WIDTH: - return m_Width; - case FXDC_PIXEL_HEIGHT: - return m_Height; - case FXDC_BITS_PIXEL: - return m_nBitsPerPixel; - case FXDC_RENDER_CAPS: - return m_bCmykOutput ? FXRC_BIT_MASK | FXRC_CMYK_OUTPUT : FXRC_BIT_MASK; - case FXDC_HORZ_SIZE: - return m_HorzSize; - case FXDC_VERT_SIZE: - return m_VertSize; - } - return 0; +int CPSPrinterDriver::GetDeviceCaps(int caps_id) { + switch (caps_id) { + case FXDC_DEVICE_CLASS: + return FXDC_PRINTER; + case FXDC_PIXEL_WIDTH: + return m_Width; + case FXDC_PIXEL_HEIGHT: + return m_Height; + case FXDC_BITS_PIXEL: + return m_nBitsPerPixel; + case FXDC_RENDER_CAPS: + return m_bCmykOutput ? FXRC_BIT_MASK | FXRC_CMYK_OUTPUT : FXRC_BIT_MASK; + case FXDC_HORZ_SIZE: + return m_HorzSize; + case FXDC_VERT_SIZE: + return m_VertSize; + } + return 0; } -FX_BOOL CPSPrinterDriver::StartRendering() -{ - return m_PSRenderer.StartRendering(); +FX_BOOL CPSPrinterDriver::StartRendering() { + return m_PSRenderer.StartRendering(); } -void CPSPrinterDriver::EndRendering() -{ - m_PSRenderer.EndRendering(); +void CPSPrinterDriver::EndRendering() { + m_PSRenderer.EndRendering(); } -void CPSPrinterDriver::SaveState() -{ - m_PSRenderer.SaveState(); +void CPSPrinterDriver::SaveState() { + m_PSRenderer.SaveState(); } -void CPSPrinterDriver::RestoreState(FX_BOOL bKeepSaved) -{ - m_PSRenderer.RestoreState(bKeepSaved); +void CPSPrinterDriver::RestoreState(FX_BOOL bKeepSaved) { + m_PSRenderer.RestoreState(bKeepSaved); } -FX_BOOL CPSPrinterDriver::SetClip_PathFill(const CFX_PathData* pPathData, const CFX_AffineMatrix* pObject2Device, - int fill_mode) -{ - m_PSRenderer.SetClip_PathFill(pPathData, pObject2Device, fill_mode); - return TRUE; +FX_BOOL CPSPrinterDriver::SetClip_PathFill( + const CFX_PathData* pPathData, + const CFX_AffineMatrix* pObject2Device, + int fill_mode) { + m_PSRenderer.SetClip_PathFill(pPathData, pObject2Device, fill_mode); + return TRUE; } -FX_BOOL CPSPrinterDriver::SetClip_PathStroke(const CFX_PathData* pPathData, - const CFX_AffineMatrix* pObject2Device, - const CFX_GraphStateData* pGraphState) -{ - m_PSRenderer.SetClip_PathStroke(pPathData, pObject2Device, pGraphState); - return TRUE; +FX_BOOL CPSPrinterDriver::SetClip_PathStroke( + const CFX_PathData* pPathData, + const CFX_AffineMatrix* pObject2Device, + const CFX_GraphStateData* pGraphState) { + m_PSRenderer.SetClip_PathStroke(pPathData, pObject2Device, pGraphState); + return TRUE; } -FX_BOOL CPSPrinterDriver::DrawPath(const CFX_PathData* pPathData, +FX_BOOL CPSPrinterDriver::DrawPath(const CFX_PathData* pPathData, const CFX_AffineMatrix* pObject2Device, - const CFX_GraphStateData* pGraphState, FX_ARGB fill_color, FX_ARGB stroke_color, - int fill_mode, int alpha_flag, void* pIccTransform, int blend_type) -{ - if (blend_type != FXDIB_BLEND_NORMAL) { - return FALSE; - } - return m_PSRenderer.DrawPath(pPathData, pObject2Device, pGraphState, fill_color, stroke_color, fill_mode & 3, alpha_flag, pIccTransform); + const CFX_GraphStateData* pGraphState, + FX_ARGB fill_color, + FX_ARGB stroke_color, + int fill_mode, + int alpha_flag, + void* pIccTransform, + int blend_type) { + if (blend_type != FXDIB_BLEND_NORMAL) { + return FALSE; + } + return m_PSRenderer.DrawPath(pPathData, pObject2Device, pGraphState, + fill_color, stroke_color, fill_mode & 3, + alpha_flag, pIccTransform); } -FX_BOOL CPSPrinterDriver::GetClipBox(FX_RECT* pRect) -{ - *pRect = m_PSRenderer.GetClipBox(); - return TRUE; +FX_BOOL CPSPrinterDriver::GetClipBox(FX_RECT* pRect) { + *pRect = m_PSRenderer.GetClipBox(); + return TRUE; } -FX_BOOL CPSPrinterDriver::SetDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, const FX_RECT* pSrcRect, int left, int top, int blend_type, - int alpha_flag, void* pIccTransform) -{ - if (blend_type != FXDIB_BLEND_NORMAL) { - return FALSE; - } - return m_PSRenderer.SetDIBits(pBitmap, color, left, top, alpha_flag, pIccTransform); +FX_BOOL CPSPrinterDriver::SetDIBits(const CFX_DIBSource* pBitmap, + FX_DWORD color, + const FX_RECT* pSrcRect, + int left, + int top, + int blend_type, + int alpha_flag, + void* pIccTransform) { + if (blend_type != FXDIB_BLEND_NORMAL) { + return FALSE; + } + return m_PSRenderer.SetDIBits(pBitmap, color, left, top, alpha_flag, + pIccTransform); } -FX_BOOL CPSPrinterDriver::StretchDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, int dest_left, int dest_top, - int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags, - int alpha_flag, void* pIccTransform, int blend_type) -{ - if (blend_type != FXDIB_BLEND_NORMAL) { - return FALSE; - } - return m_PSRenderer.StretchDIBits(pBitmap, color, dest_left, dest_top, dest_width, dest_height, flags, alpha_flag, pIccTransform); +FX_BOOL CPSPrinterDriver::StretchDIBits(const CFX_DIBSource* pBitmap, + FX_DWORD color, + int dest_left, + int dest_top, + int dest_width, + int dest_height, + const FX_RECT* pClipRect, + FX_DWORD flags, + int alpha_flag, + void* pIccTransform, + int blend_type) { + if (blend_type != FXDIB_BLEND_NORMAL) { + return FALSE; + } + return m_PSRenderer.StretchDIBits(pBitmap, color, dest_left, dest_top, + dest_width, dest_height, flags, alpha_flag, + pIccTransform); } -FX_BOOL CPSPrinterDriver::StartDIBits(const CFX_DIBSource* pBitmap, int bitmap_alpha, FX_DWORD color, - const CFX_AffineMatrix* pMatrix, FX_DWORD render_flags, void*& handle, - int alpha_flag, void* pIccTransform, int blend_type) -{ - if (blend_type != FXDIB_BLEND_NORMAL) { - return FALSE; - } - if (bitmap_alpha < 255) { - return FALSE; - } - handle = NULL; - return m_PSRenderer.DrawDIBits(pBitmap, color, pMatrix, render_flags, alpha_flag, pIccTransform); +FX_BOOL CPSPrinterDriver::StartDIBits(const CFX_DIBSource* pBitmap, + int bitmap_alpha, + FX_DWORD color, + const CFX_AffineMatrix* pMatrix, + FX_DWORD render_flags, + void*& handle, + int alpha_flag, + void* pIccTransform, + int blend_type) { + if (blend_type != FXDIB_BLEND_NORMAL) { + return FALSE; + } + if (bitmap_alpha < 255) { + return FALSE; + } + handle = NULL; + return m_PSRenderer.DrawDIBits(pBitmap, color, pMatrix, render_flags, + alpha_flag, pIccTransform); } -FX_BOOL CPSPrinterDriver::DrawDeviceText(int nChars, const FXTEXT_CHARPOS* pCharPos, CFX_Font* pFont, - CFX_FontCache* pCache, const CFX_AffineMatrix* pObject2Device, FX_FLOAT font_size, FX_DWORD color, - int alpha_flag, void* pIccTransform) -{ - return m_PSRenderer.DrawText(nChars, pCharPos, pFont, pCache, pObject2Device, font_size, color, alpha_flag, pIccTransform); +FX_BOOL CPSPrinterDriver::DrawDeviceText(int nChars, + const FXTEXT_CHARPOS* pCharPos, + CFX_Font* pFont, + CFX_FontCache* pCache, + const CFX_AffineMatrix* pObject2Device, + FX_FLOAT font_size, + FX_DWORD color, + int alpha_flag, + void* pIccTransform) { + return m_PSRenderer.DrawText(nChars, pCharPos, pFont, pCache, pObject2Device, + font_size, color, alpha_flag, pIccTransform); } #endif diff --git a/core/src/fxge/win32/win32_int.h b/core/src/fxge/win32/win32_int.h index 569c4f6baa..cb3b017ad8 100644 --- a/core/src/fxge/win32/win32_int.h +++ b/core/src/fxge/win32/win32_int.h @@ -6,237 +6,348 @@ #ifndef CORE_SRC_FXGE_WIN32_WIN32_INT_H_ #define CORE_SRC_FXGE_WIN32_WIN32_INT_H_ -struct WINDIB_Open_Args_; -class CGdiplusExt -{ -public: - CGdiplusExt(); - ~CGdiplusExt(); - void Load(); - FX_BOOL IsAvailable() - { - return m_hModule != NULL; - } - FX_BOOL StretchBitMask(HDC hDC, BOOL bMonoDevice, const CFX_DIBitmap* pBitmap, int dest_left, int dest_top, - int dest_width, int dest_height, FX_DWORD argb, const FX_RECT* pClipRect, int flags); - FX_BOOL StretchDIBits(HDC hDC, const CFX_DIBitmap* pBitmap, int dest_left, int dest_top, - int dest_width, int dest_height, const FX_RECT* pClipRect, int flags); - FX_BOOL DrawPath(HDC hDC, const CFX_PathData* pPathData, - const CFX_AffineMatrix* pObject2Device, - const CFX_GraphStateData* pGraphState, - FX_DWORD fill_argb, - FX_DWORD stroke_argb, - int fill_mode - ); +struct WINDIB_Open_Args_; +class CGdiplusExt { + public: + CGdiplusExt(); + ~CGdiplusExt(); + void Load(); + FX_BOOL IsAvailable() { return m_hModule != NULL; } + FX_BOOL StretchBitMask(HDC hDC, + BOOL bMonoDevice, + const CFX_DIBitmap* pBitmap, + int dest_left, + int dest_top, + int dest_width, + int dest_height, + FX_DWORD argb, + const FX_RECT* pClipRect, + int flags); + FX_BOOL StretchDIBits(HDC hDC, + const CFX_DIBitmap* pBitmap, + int dest_left, + int dest_top, + int dest_width, + int dest_height, + const FX_RECT* pClipRect, + int flags); + FX_BOOL DrawPath(HDC hDC, + const CFX_PathData* pPathData, + const CFX_AffineMatrix* pObject2Device, + const CFX_GraphStateData* pGraphState, + FX_DWORD fill_argb, + FX_DWORD stroke_argb, + int fill_mode); + + void* LoadMemFont(uint8_t* pData, FX_DWORD size); + void DeleteMemFont(void* pFontCollection); + FX_BOOL GdipCreateFromImage(void* bitmap, void** graphics); + void GdipDeleteGraphics(void* graphics); + void GdipSetTextRenderingHint(void* graphics, int mode); + void GdipSetPageUnit(void* graphics, FX_DWORD unit); + void GdipSetWorldTransform(void* graphics, void* pMatrix); + FX_BOOL GdipDrawDriverString(void* graphics, + unsigned short* text, + int length, + void* font, + void* brush, + void* positions, + int flags, + const void* matrix); + void GdipCreateBrush(FX_DWORD fill_argb, void** pBrush); + void GdipDeleteBrush(void* pBrush); + void GdipCreateMatrix(FX_FLOAT a, + FX_FLOAT b, + FX_FLOAT c, + FX_FLOAT d, + FX_FLOAT e, + FX_FLOAT f, + void** matrix); + void GdipDeleteMatrix(void* matrix); + FX_BOOL GdipCreateFontFamilyFromName(const FX_WCHAR* name, + void* pFontCollection, + void** pFamily); + void GdipDeleteFontFamily(void* pFamily); + FX_BOOL GdipCreateFontFromFamily(void* pFamily, + FX_FLOAT font_size, + int fontstyle, + int flag, + void** pFont); + void* GdipCreateFontFromCollection(void* pFontCollection, + FX_FLOAT font_size, + int fontstyle); + void GdipDeleteFont(void* pFont); + FX_BOOL GdipCreateBitmap(CFX_DIBitmap* pBitmap, void** bitmap); + void GdipDisposeImage(void* bitmap); + void GdipGetFontSize(void* pFont, FX_FLOAT* size); + void* GdiAddFontMemResourceEx(void* pFontdata, + FX_DWORD size, + void* pdv, + FX_DWORD* num_face); + FX_BOOL GdiRemoveFontMemResourceEx(void* handle); + void* m_Functions[100]; + void* m_pGdiAddFontMemResourceEx; + void* m_pGdiRemoveFontMemResourseEx; + CFX_DIBitmap* LoadDIBitmap(WINDIB_Open_Args_ args); - void* LoadMemFont(uint8_t* pData, FX_DWORD size); - void DeleteMemFont(void* pFontCollection); - FX_BOOL GdipCreateFromImage(void* bitmap, void** graphics); - void GdipDeleteGraphics(void* graphics); - void GdipSetTextRenderingHint(void* graphics, int mode); - void GdipSetPageUnit(void* graphics, FX_DWORD unit); - void GdipSetWorldTransform(void* graphics, void* pMatrix); - FX_BOOL GdipDrawDriverString(void *graphics, unsigned short *text, int length, void *font, void* brush, void *positions, int flags, const void *matrix); - void GdipCreateBrush(FX_DWORD fill_argb, void** pBrush); - void GdipDeleteBrush(void* pBrush); - void GdipCreateMatrix(FX_FLOAT a, FX_FLOAT b, FX_FLOAT c, FX_FLOAT d, FX_FLOAT e, FX_FLOAT f, void** matrix); - void GdipDeleteMatrix(void* matrix); - FX_BOOL GdipCreateFontFamilyFromName(const FX_WCHAR* name, void* pFontCollection, void**pFamily); - void GdipDeleteFontFamily(void* pFamily); - FX_BOOL GdipCreateFontFromFamily(void* pFamily, FX_FLOAT font_size, int fontstyle, int flag, void** pFont); - void* GdipCreateFontFromCollection(void* pFontCollection, FX_FLOAT font_size, int fontstyle); - void GdipDeleteFont(void* pFont); - FX_BOOL GdipCreateBitmap(CFX_DIBitmap* pBitmap, void**bitmap); - void GdipDisposeImage(void* bitmap); - void GdipGetFontSize(void *pFont, FX_FLOAT *size); - void* GdiAddFontMemResourceEx(void *pFontdata, FX_DWORD size, void* pdv, FX_DWORD* num_face); - FX_BOOL GdiRemoveFontMemResourceEx(void* handle); - void* m_Functions[100]; - void* m_pGdiAddFontMemResourceEx; - void* m_pGdiRemoveFontMemResourseEx; - CFX_DIBitmap* LoadDIBitmap(WINDIB_Open_Args_ args); -protected: - HMODULE m_hModule; - HMODULE m_GdiModule; + protected: + HMODULE m_hModule; + HMODULE m_GdiModule; }; #include "dwrite_int.h" -class CWin32Platform -{ -public: - FX_BOOL m_bHalfTone; - CGdiplusExt m_GdiplusExt; - CDWriteExt m_DWriteExt; +class CWin32Platform { + public: + FX_BOOL m_bHalfTone; + CGdiplusExt m_GdiplusExt; + CDWriteExt m_DWriteExt; }; -class CGdiDeviceDriver : public IFX_RenderDeviceDriver -{ -protected: - virtual int GetDeviceCaps(int caps_id); - virtual void SaveState() - { - SaveDC(m_hDC); - } - virtual void RestoreState(FX_BOOL bKeepSaved = FALSE) - { - RestoreDC(m_hDC, -1); - if (bKeepSaved) { - SaveDC(m_hDC); - } +class CGdiDeviceDriver : public IFX_RenderDeviceDriver { + protected: + virtual int GetDeviceCaps(int caps_id); + virtual void SaveState() { SaveDC(m_hDC); } + virtual void RestoreState(FX_BOOL bKeepSaved = FALSE) { + RestoreDC(m_hDC, -1); + if (bKeepSaved) { + SaveDC(m_hDC); } - virtual FX_BOOL SetClip_PathFill(const CFX_PathData* pPathData, + } + virtual FX_BOOL SetClip_PathFill(const CFX_PathData* pPathData, + const CFX_AffineMatrix* pObject2Device, + int fill_mode); + virtual FX_BOOL SetClip_PathStroke(const CFX_PathData* pPathData, const CFX_AffineMatrix* pObject2Device, - int fill_mode - ); - virtual FX_BOOL SetClip_PathStroke(const CFX_PathData* pPathData, - const CFX_AffineMatrix* pObject2Device, - const CFX_GraphStateData* pGraphState - ); - virtual FX_BOOL DrawPath(const CFX_PathData* pPathData, - const CFX_AffineMatrix* pObject2Device, - const CFX_GraphStateData* pGraphState, - FX_DWORD fill_color, - FX_DWORD stroke_color, - int fill_mode, + const CFX_GraphStateData* pGraphState); + virtual FX_BOOL DrawPath(const CFX_PathData* pPathData, + const CFX_AffineMatrix* pObject2Device, + const CFX_GraphStateData* pGraphState, + FX_DWORD fill_color, + FX_DWORD stroke_color, + int fill_mode, + int alpha_flag, + void* pIccTransform, + int blend_type); + virtual FX_BOOL FillRect(const FX_RECT* pRect, + FX_DWORD fill_color, + int alpha_flag, + void* pIccTransform, + int blend_type); + virtual FX_BOOL DrawCosmeticLine(FX_FLOAT x1, + FX_FLOAT y1, + FX_FLOAT x2, + FX_FLOAT y2, + FX_DWORD color, + int alpha_flag, + void* pIccTransform, + int blend_type); + virtual void* GetClipRgn(); + virtual FX_BOOL SetClipRgn(void* pRgn); + virtual FX_BOOL GetClipBox(FX_RECT* pRect); + virtual FX_BOOL DeleteDeviceRgn(void* pRgn); + virtual void DrawLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2); + virtual void* GetPlatformSurface() { return (void*)m_hDC; } + FX_BOOL GDI_SetDIBits(const CFX_DIBitmap* pBitmap, + const FX_RECT* pSrcRect, + int left, + int top, + void* pIccTransform); + FX_BOOL GDI_StretchDIBits(const CFX_DIBitmap* pBitmap, + int dest_left, + int dest_top, + int dest_width, + int dest_height, + FX_DWORD flags, + void* pIccTransform); + FX_BOOL GDI_StretchBitMask(const CFX_DIBitmap* pBitmap, + int dest_left, + int dest_top, + int dest_width, + int dest_height, + FX_DWORD bitmap_color, + FX_DWORD flags, int alpha_flag, - void* pIccTransform, - int blend_type - ); - virtual FX_BOOL FillRect(const FX_RECT* pRect, - FX_DWORD fill_color, - int alpha_flag, void* pIccTransform, int blend_type); - virtual FX_BOOL DrawCosmeticLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2, FX_DWORD color, - int alpha_flag, void* pIccTransform, int blend_type); - virtual void* GetClipRgn() ; - virtual FX_BOOL SetClipRgn(void* pRgn) ; - virtual FX_BOOL GetClipBox(FX_RECT* pRect); - virtual FX_BOOL DeleteDeviceRgn(void* pRgn); - virtual void DrawLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2); - virtual void* GetPlatformSurface() - { - return (void*)m_hDC; - } - FX_BOOL GDI_SetDIBits(const CFX_DIBitmap* pBitmap, const FX_RECT* pSrcRect, int left, int top, - void* pIccTransform); - FX_BOOL GDI_StretchDIBits(const CFX_DIBitmap* pBitmap, int dest_left, int dest_top, - int dest_width, int dest_height, FX_DWORD flags, - void* pIccTransform); - FX_BOOL GDI_StretchBitMask(const CFX_DIBitmap* pBitmap, int dest_left, int dest_top, - int dest_width, int dest_height, FX_DWORD bitmap_color, FX_DWORD flags, - int alpha_flag, void* pIccTransform); - HDC m_hDC; - int m_Width, m_Height, m_nBitsPerPixel; - int m_DeviceClass, m_RenderCaps; - CGdiDeviceDriver(HDC hDC, int device_class); - ~CGdiDeviceDriver() {} + void* pIccTransform); + HDC m_hDC; + int m_Width, m_Height, m_nBitsPerPixel; + int m_DeviceClass, m_RenderCaps; + CGdiDeviceDriver(HDC hDC, int device_class); + ~CGdiDeviceDriver() {} }; -class CGdiDisplayDriver : public CGdiDeviceDriver -{ -public: - CGdiDisplayDriver(HDC hDC); -protected: - virtual FX_BOOL GetDIBits(CFX_DIBitmap* pBitmap, int left, int top, void* pIccTransform = NULL, FX_BOOL bDEdge = FALSE); - virtual FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, const FX_RECT* pSrcRect, int left, int top, int blend_type, - int alpha_flag, void* pIccTransform); - virtual FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, int dest_left, int dest_top, - int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags, - int alpha_flag, void* pIccTransform, int blend_type); - virtual FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap, int bitmap_alpha, FX_DWORD color, - const CFX_AffineMatrix* pMatrix, FX_DWORD render_flags, void*& handle, - int alpha_flag, void* pIccTransform, int blend_type) - { - return FALSE; - } - FX_BOOL UseFoxitStretchEngine(const CFX_DIBSource* pSource, FX_DWORD color, int dest_left, int dest_top, - int dest_width, int dest_height, const FX_RECT* pClipRect, int render_flags, - int alpha_flag = 0, void* pIccTransform = NULL, int blend_type = FXDIB_BLEND_NORMAL); +class CGdiDisplayDriver : public CGdiDeviceDriver { + public: + CGdiDisplayDriver(HDC hDC); + + protected: + virtual FX_BOOL GetDIBits(CFX_DIBitmap* pBitmap, + int left, + int top, + void* pIccTransform = NULL, + FX_BOOL bDEdge = FALSE); + virtual FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap, + FX_DWORD color, + const FX_RECT* pSrcRect, + int left, + int top, + int blend_type, + int alpha_flag, + void* pIccTransform); + virtual FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap, + FX_DWORD color, + int dest_left, + int dest_top, + int dest_width, + int dest_height, + const FX_RECT* pClipRect, + FX_DWORD flags, + int alpha_flag, + void* pIccTransform, + int blend_type); + virtual FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap, + int bitmap_alpha, + FX_DWORD color, + const CFX_AffineMatrix* pMatrix, + FX_DWORD render_flags, + void*& handle, + int alpha_flag, + void* pIccTransform, + int blend_type) { + return FALSE; + } + FX_BOOL UseFoxitStretchEngine(const CFX_DIBSource* pSource, + FX_DWORD color, + int dest_left, + int dest_top, + int dest_width, + int dest_height, + const FX_RECT* pClipRect, + int render_flags, + int alpha_flag = 0, + void* pIccTransform = NULL, + int blend_type = FXDIB_BLEND_NORMAL); }; -class CGdiPrinterDriver : public CGdiDeviceDriver -{ -public: - CGdiPrinterDriver(HDC hDC); -protected: - virtual int GetDeviceCaps(int caps_id); - virtual FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, const FX_RECT* pSrcRect, int left, int top, int blend_type, - int alpha_flag, void* pIccTransform); - virtual FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, int dest_left, int dest_top, - int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags, - int alpha_flag, void* pIccTransform, int blend_type); - virtual FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap, int bitmap_alpha, FX_DWORD color, - const CFX_AffineMatrix* pMatrix, FX_DWORD render_flags, void*& handle, - int alpha_flag, void* pIccTransform, int blend_type); - int m_HorzSize, m_VertSize; - FX_BOOL m_bSupportROP; +class CGdiPrinterDriver : public CGdiDeviceDriver { + public: + CGdiPrinterDriver(HDC hDC); + + protected: + virtual int GetDeviceCaps(int caps_id); + virtual FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap, + FX_DWORD color, + const FX_RECT* pSrcRect, + int left, + int top, + int blend_type, + int alpha_flag, + void* pIccTransform); + virtual FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap, + FX_DWORD color, + int dest_left, + int dest_top, + int dest_width, + int dest_height, + const FX_RECT* pClipRect, + FX_DWORD flags, + int alpha_flag, + void* pIccTransform, + int blend_type); + virtual FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap, + int bitmap_alpha, + FX_DWORD color, + const CFX_AffineMatrix* pMatrix, + FX_DWORD render_flags, + void*& handle, + int alpha_flag, + void* pIccTransform, + int blend_type); + int m_HorzSize, m_VertSize; + FX_BOOL m_bSupportROP; }; -class CPSOutput : public IFX_PSOutput -{ -public: - CPSOutput(HDC hDC); - virtual ~CPSOutput(); - virtual void Release() - { - delete this; - } - void Init(); - virtual void OutputPS(const FX_CHAR* string, int len); - HDC m_hDC; - FX_CHAR* m_pBuf; +class CPSOutput : public IFX_PSOutput { + public: + CPSOutput(HDC hDC); + virtual ~CPSOutput(); + virtual void Release() { delete this; } + void Init(); + virtual void OutputPS(const FX_CHAR* string, int len); + HDC m_hDC; + FX_CHAR* m_pBuf; }; -class CPSPrinterDriver : public IFX_RenderDeviceDriver -{ -public: - CPSPrinterDriver(); - FX_BOOL Init(HDC hDC, int ps_level, FX_BOOL bCmykOutput); - ~CPSPrinterDriver(); -protected: - virtual FX_BOOL IsPSPrintDriver() - { - return TRUE; - } - virtual int GetDeviceCaps(int caps_id); - virtual FX_BOOL StartRendering(); - virtual void EndRendering(); - virtual void SaveState(); - virtual void RestoreState(FX_BOOL bKeepSaved = FALSE); - virtual FX_BOOL SetClip_PathFill(const CFX_PathData* pPathData, +class CPSPrinterDriver : public IFX_RenderDeviceDriver { + public: + CPSPrinterDriver(); + FX_BOOL Init(HDC hDC, int ps_level, FX_BOOL bCmykOutput); + ~CPSPrinterDriver(); + + protected: + virtual FX_BOOL IsPSPrintDriver() { return TRUE; } + virtual int GetDeviceCaps(int caps_id); + virtual FX_BOOL StartRendering(); + virtual void EndRendering(); + virtual void SaveState(); + virtual void RestoreState(FX_BOOL bKeepSaved = FALSE); + virtual FX_BOOL SetClip_PathFill(const CFX_PathData* pPathData, + const CFX_AffineMatrix* pObject2Device, + int fill_mode); + virtual FX_BOOL SetClip_PathStroke(const CFX_PathData* pPathData, const CFX_AffineMatrix* pObject2Device, - int fill_mode - ); - virtual FX_BOOL SetClip_PathStroke(const CFX_PathData* pPathData, - const CFX_AffineMatrix* pObject2Device, - const CFX_GraphStateData* pGraphState - ); - virtual FX_BOOL DrawPath(const CFX_PathData* pPathData, - const CFX_AffineMatrix* pObject2Device, - const CFX_GraphStateData* pGraphState, - FX_DWORD fill_color, - FX_DWORD stroke_color, - int fill_mode, - int alpha_flag, - void* pIccTransform, - int blend_type - ); - virtual FX_BOOL GetClipBox(FX_RECT* pRect); - virtual FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, const FX_RECT* pSrcRect, int left, int top, int blend_type, - int alpha_flag, void* pIccTransform); - virtual FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, int dest_left, int dest_top, - int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags, - int alpha_flag, void* pIccTransform, int blend_type); - virtual FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap, int bitmap_alpha, FX_DWORD color, - const CFX_AffineMatrix* pMatrix, FX_DWORD render_flags, void*& handle, - int alpha_flag, void* pIccTransform, int blend_type); - virtual FX_BOOL DrawDeviceText(int nChars, const FXTEXT_CHARPOS* pCharPos, CFX_Font* pFont, - CFX_FontCache* pCache, const CFX_AffineMatrix* pObject2Device, FX_FLOAT font_size, FX_DWORD color, - int alpha_flag, void* pIccTransform); - virtual void* GetPlatformSurface() - { - return (void*)m_hDC; - } - HDC m_hDC; - FX_BOOL m_bCmykOutput; - int m_Width, m_Height, m_nBitsPerPixel; - int m_HorzSize, m_VertSize; - CPSOutput* m_pPSOutput; - CFX_PSRenderer m_PSRenderer; + const CFX_GraphStateData* pGraphState); + virtual FX_BOOL DrawPath(const CFX_PathData* pPathData, + const CFX_AffineMatrix* pObject2Device, + const CFX_GraphStateData* pGraphState, + FX_DWORD fill_color, + FX_DWORD stroke_color, + int fill_mode, + int alpha_flag, + void* pIccTransform, + int blend_type); + virtual FX_BOOL GetClipBox(FX_RECT* pRect); + virtual FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap, + FX_DWORD color, + const FX_RECT* pSrcRect, + int left, + int top, + int blend_type, + int alpha_flag, + void* pIccTransform); + virtual FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap, + FX_DWORD color, + int dest_left, + int dest_top, + int dest_width, + int dest_height, + const FX_RECT* pClipRect, + FX_DWORD flags, + int alpha_flag, + void* pIccTransform, + int blend_type); + virtual FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap, + int bitmap_alpha, + FX_DWORD color, + const CFX_AffineMatrix* pMatrix, + FX_DWORD render_flags, + void*& handle, + int alpha_flag, + void* pIccTransform, + int blend_type); + virtual FX_BOOL DrawDeviceText(int nChars, + const FXTEXT_CHARPOS* pCharPos, + CFX_Font* pFont, + CFX_FontCache* pCache, + const CFX_AffineMatrix* pObject2Device, + FX_FLOAT font_size, + FX_DWORD color, + int alpha_flag, + void* pIccTransform); + virtual void* GetPlatformSurface() { return (void*)m_hDC; } + HDC m_hDC; + FX_BOOL m_bCmykOutput; + int m_Width, m_Height, m_nBitsPerPixel; + int m_HorzSize, m_VertSize; + CPSOutput* m_pPSOutput; + CFX_PSRenderer m_PSRenderer; }; -void _Color2Argb(FX_ARGB& argb, FX_DWORD color, int alpha_flag, void* pIccTransform); +void _Color2Argb(FX_ARGB& argb, + FX_DWORD color, + int alpha_flag, + void* pIccTransform); #endif // CORE_SRC_FXGE_WIN32_WIN32_INT_H_ -- cgit v1.2.3