Commit 0723ad34 authored by Oleg Korshul's avatar Oleg Korshul Committed by Alexander Trofimov

субпиксельный рендеринг текста

parent 9fa776d1
...@@ -153,6 +153,21 @@ namespace agg ...@@ -153,6 +153,21 @@ namespace agg
p[Order::B] = (value_type)(((cb - b) * alpha + (b << base_shift)) >> base_shift); p[Order::B] = (value_type)(((cb - b) * alpha + (b << base_shift)) >> base_shift);
p[Order::A] = (value_type)((alpha + a) - ((alpha * a + base_mask) >> base_shift)); p[Order::A] = (value_type)((alpha + a) - ((alpha * a + base_mask) >> base_shift));
} }
static AGG_INLINE void blend_pix_subpix(value_type* p,
unsigned cr, unsigned cg, unsigned cb,
unsigned* covers,
unsigned cover=0)
{
calc_type r = p[Order::R];
calc_type g = p[Order::G];
calc_type b = p[Order::B];
//calc_type a = p[Order::A];
p[Order::R] = (value_type)(((cr - r) * covers[Order::R] + (r << base_shift)) >> base_shift);
p[Order::G] = (value_type)(((cg - g) * covers[Order::G] + (g << base_shift)) >> base_shift);
p[Order::B] = (value_type)(((cb - b) * covers[Order::B] + (b << base_shift)) >> base_shift);
//p[Order::A] = (value_type)((alpha + a) - ((alpha * a + base_mask) >> base_shift));
}
}; };
//=========================================================blender_rgba_pre //=========================================================blender_rgba_pre
...@@ -2025,6 +2040,28 @@ namespace agg ...@@ -2025,6 +2040,28 @@ namespace agg
} }
} }
void blend_solid_hspan_subpix(int x, int y,
unsigned len,
const color_type& c,
const int8u* covers)
{
if (c.a)
{
value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2);
calc_type covers_alpha[4];
do
{
covers_alpha[order_type::R] = (calc_type(c.a) * (calc_type(*covers++) + 1)) >> 8;
covers_alpha[order_type::G] = (calc_type(c.a) * (calc_type(*covers++) + 1)) >> 8;
covers_alpha[order_type::B] = (calc_type(c.a) * (calc_type(*covers++) + 1)) >> 8;
blender_type::blend_pix_subpix(p, c.r, c.g, c.b, covers_alpha, *covers);
p += 4;
}
while(--len);
}
}
//-------------------------------------------------------------------- //--------------------------------------------------------------------
void blend_solid_vspan(int x, int y, void blend_solid_vspan(int x, int y,
......
...@@ -281,6 +281,28 @@ namespace agg ...@@ -281,6 +281,28 @@ namespace agg
m_ren->blend_solid_hspan(x, y, len, c, covers); m_ren->blend_solid_hspan(x, y, len, c, covers);
} }
void blend_solid_hspan_subpix(int x, int y, int len,
const color_type& c,
const cover_type* covers)
{
if(y > ymax()) return;
if(y < ymin()) return;
if(x < xmin())
{
len -= xmin() - x;
if(len <= 0) return;
covers += ((xmin() - x) * 3);
x = xmin();
}
if(x + len > xmax())
{
len = xmax() - x + 1;
if(len <= 0) return;
}
m_ren->blend_solid_hspan_subpix(x, y, len, c, covers);
}
//-------------------------------------------------------------------- //--------------------------------------------------------------------
void blend_solid_vspan(int x, int y, int len, void blend_solid_vspan(int x, int y, int len,
const color_type& c, const color_type& c,
......
...@@ -149,6 +149,16 @@ namespace agg ...@@ -149,6 +149,16 @@ namespace agg
pMemory += lWidth; pMemory += lWidth;
} }
} }
inline void render_subpix(int lWidth, int lHeight, unsigned char* pData, int x, int y)
{
unsigned char* pMemory = pData;
for (int j = 0; j < lHeight; ++j)
{
m_ren->blend_solid_hspan_subpix(x, y + j, lWidth, m_color, pMemory);
pMemory += lWidth * 3;
}
}
private: private:
base_ren_type* m_ren; base_ren_type* m_ren;
......
...@@ -1177,7 +1177,7 @@ INT CFontFile::GetString2(CGlyphString& oString) ...@@ -1177,7 +1177,7 @@ INT CFontFile::GetString2(CGlyphString& oString)
oSizes.oMetrics.fWidth = (float)(pFace->glyph->metrics.width >> 6); oSizes.oMetrics.fWidth = (float)(pFace->glyph->metrics.width >> 6);
pCurGlyph->bBitmap = true; pCurGlyph->bBitmap = true;
if (FT_Render_Glyph(pCurentGliph, REND_MODE)) if (FT_Render_Glyph(pCurentGliph, (FT_Render_Mode)m_pFontManager->m_nRENDER_MODE))
return FALSE; return FALSE;
TGlyphBitmap *pBitmap = &(pCurGlyph->oBitmap); TGlyphBitmap *pBitmap = &(pCurGlyph->oBitmap);
...@@ -1457,7 +1457,7 @@ INT CFontFile::GetString2C(CGlyphString& oString) ...@@ -1457,7 +1457,7 @@ INT CFontFile::GetString2C(CGlyphString& oString)
oSizes.oMetrics.fWidth = (float)(pFace->glyph->metrics.width >> 6); oSizes.oMetrics.fWidth = (float)(pFace->glyph->metrics.width >> 6);
pCurGlyph->bBitmap = true; pCurGlyph->bBitmap = true;
if (FT_Render_Glyph(pCurentGliph, REND_MODE)) if (FT_Render_Glyph(pCurentGliph, (FT_Render_Mode)m_pFontManager->m_nRENDER_MODE))
return FALSE; return FALSE;
TGlyphBitmap *pBitmap = &(pCurGlyph->oBitmap); TGlyphBitmap *pBitmap = &(pCurGlyph->oBitmap);
......
...@@ -100,7 +100,6 @@ private: ...@@ -100,7 +100,6 @@ private:
}; };
#define LOAD_MODE FT_LOAD_NO_HINTING | FT_LOAD_NO_AUTOHINT | FT_LOAD_NO_BITMAP | FT_LOAD_LINEAR_DESIGN #define LOAD_MODE FT_LOAD_NO_HINTING | FT_LOAD_NO_AUTOHINT | FT_LOAD_NO_BITMAP | FT_LOAD_LINEAR_DESIGN
#define REND_MODE FT_RENDER_MODE_NORMAL
#define FONT_ITALIC_ANGLE 0.3090169943749 // Синус 18 градусов (подбиралось под Word 2007) #define FONT_ITALIC_ANGLE 0.3090169943749 // Синус 18 градусов (подбиралось под Word 2007)
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#include "../common/File.h" #include "../common/File.h"
#include <stdio.h> #include <stdio.h>
#include "ftsnames.h" #include "ftsnames.h"
#include FT_LCD_FILTER_H
/////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////
CFontStream::CFontStream() CFontStream::CFontStream()
...@@ -205,6 +206,7 @@ CFontManager::CFontManager() ...@@ -205,6 +206,7 @@ CFontManager::CFontManager()
{ {
m_pLibrary = NULL; m_pLibrary = NULL;
FT_Init_FreeType(&m_pLibrary); FT_Init_FreeType(&m_pLibrary);
FT_Library_SetLcdFilter(m_pLibrary, FT_LCD_FILTER_DEFAULT);
m_pFont = NULL; m_pFont = NULL;
m_pApplication = NULL; m_pApplication = NULL;
...@@ -214,6 +216,8 @@ CFontManager::CFontManager() ...@@ -214,6 +216,8 @@ CFontManager::CFontManager()
m_nLOAD_MODE = 40968; m_nLOAD_MODE = 40968;
m_lRef = 1; m_lRef = 1;
m_nRENDER_MODE = FT_RENDER_MODE_NORMAL;
m_bUseDefaultFont = FALSE; m_bUseDefaultFont = FALSE;
m_fCharSpacing = 0; m_fCharSpacing = 0;
...@@ -704,3 +708,13 @@ unsigned int CFontManager::GetNameIndex(const std::wstring& wsName) const ...@@ -704,3 +708,13 @@ unsigned int CFontManager::GetNameIndex(const std::wstring& wsName) const
return m_pFont->GetNameIndex(wsName); return m_pFont->GetNameIndex(wsName);
} }
void CFontManager::SetSubpixelRendering(const bool& hmul, const bool& vmul)
{
if (hmul)
m_nRENDER_MODE = FT_RENDER_MODE_LCD;
else if (vmul)
m_nRENDER_MODE = FT_RENDER_MODE_LCD_V;
else
m_nRENDER_MODE = FT_RENDER_MODE_NORMAL;
}
...@@ -116,6 +116,7 @@ public: ...@@ -116,6 +116,7 @@ public:
int m_lLineHeight; int m_lLineHeight;
int m_nLOAD_MODE; int m_nLOAD_MODE;
int m_nRENDER_MODE;
CApplicationFonts* m_pApplication; CApplicationFonts* m_pApplication;
CFontsCache* m_pOwnerCache; CFontsCache* m_pOwnerCache;
...@@ -169,6 +170,8 @@ public: ...@@ -169,6 +170,8 @@ public:
std::wstring GetFontType() const; std::wstring GetFontType() const;
unsigned int GetNameIndex(const std::wstring& wsName) const; unsigned int GetNameIndex(const std::wstring& wsName) const;
void SetSubpixelRendering(const bool& hmul, const bool& vmul);
public: public:
static CFontFile* LoadFontFile(FT_Library library, CFontStream* pStream, LONG lFaceIndex); static CFontFile* LoadFontFile(FT_Library library, CFontStream* pStream, LONG lFaceIndex);
......
...@@ -92,7 +92,7 @@ FT_BEGIN_HEADER ...@@ -92,7 +92,7 @@ FT_BEGIN_HEADER
/* This is done to allow FreeType clients to run unmodified, forcing */ /* This is done to allow FreeType clients to run unmodified, forcing */
/* them to display normal gray-level anti-aliased glyphs. */ /* them to display normal gray-level anti-aliased glyphs. */
/* */ /* */
/* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING
/*************************************************************************/ /*************************************************************************/
......
#include "Graphics.h" #include "Graphics.h"
#include <algorithm> #include <algorithm>
#include "../fontengine/FontFile.h"
namespace Aggplus namespace Aggplus
{ {
...@@ -33,6 +34,8 @@ namespace Aggplus ...@@ -33,6 +34,8 @@ namespace Aggplus
#endif #endif
m_dDpiTile = -1; m_dDpiTile = -1;
m_nTextRenderMode = FT_RENDER_MODE_NORMAL;
} }
CGraphics::CGraphics(int dwWidth, int dwHeight, int stride, BYTE* pBuffer) : m_dwConfigFlags(0) CGraphics::CGraphics(int dwWidth, int dwHeight, int stride, BYTE* pBuffer) : m_dwConfigFlags(0)
...@@ -968,6 +971,7 @@ namespace Aggplus ...@@ -968,6 +971,7 @@ namespace Aggplus
oM1.TransformPoint(_x, _y); oM1.TransformPoint(_x, _y);
pFont->SetTextMatrix((float)mass[0], (float)mass[1], (float)mass[2], (float)mass[3], (float)mass[4], (float)mass[5]); pFont->SetTextMatrix((float)mass[0], (float)mass[1], (float)mass[2], (float)mass[3], (float)mass[4], (float)mass[5]);
m_nTextRenderMode = pFont->m_nRENDER_MODE;
pFont->LoadString2(strText, (float)_x, (float)_y); pFont->LoadString2(strText, (float)_x, (float)_y);
float fX = 0; float fX = 0;
...@@ -1012,6 +1016,7 @@ namespace Aggplus ...@@ -1012,6 +1016,7 @@ namespace Aggplus
oM1.TransformPoint(_x, _y); oM1.TransformPoint(_x, _y);
pFont->SetTextMatrix((float)mass[0], (float)mass[1], (float)mass[2], (float)mass[3], (float)mass[4], (float)mass[5]); pFont->SetTextMatrix((float)mass[0], (float)mass[1], (float)mass[2], (float)mass[3], (float)mass[4], (float)mass[5]);
m_nTextRenderMode = pFont->m_nRENDER_MODE;
pFont->LoadString2(pGids, nGidsCount, (float)_x, (float)_y); pFont->LoadString2(pGids, nGidsCount, (float)_x, (float)_y);
float fX = 0; float fX = 0;
...@@ -1902,7 +1907,15 @@ namespace Aggplus ...@@ -1902,7 +1907,15 @@ namespace Aggplus
typedef agg::renderer_scanline_aa_solid<base_renderer_type> solid_renderer_type; typedef agg::renderer_scanline_aa_solid<base_renderer_type> solid_renderer_type;
solid_renderer_type ren_fine(m_frame_buffer.ren_base()); solid_renderer_type ren_fine(m_frame_buffer.ren_base());
ren_fine.color(clr.GetAggColor()); ren_fine.color(clr.GetAggColor());
ren_fine.render(lWidth, lHeight, pData, nX, nY);
if (m_nTextRenderMode == FT_RENDER_MODE_LCD)
{
ren_fine.render_subpix(lWidth / 3, lHeight, pData, nX, nY);
}
else
{
ren_fine.render(lWidth, lHeight, pData, nX, nY);
}
return 0; return 0;
} }
......
...@@ -15,7 +15,7 @@ int main(int argc, char *argv[]) ...@@ -15,7 +15,7 @@ int main(int argc, char *argv[])
double dWidthMM = 25.4 * nRasterW / 96; double dWidthMM = 25.4 * nRasterW / 96;
double dHeightMM = 25.4 * nRasterH / 96; double dHeightMM = 25.4 * nRasterH / 96;
if (true) if (false)
{ {
nRasterW *= 2; nRasterW *= 2;
nRasterH *= 2; nRasterH *= 2;
...@@ -30,6 +30,7 @@ int main(int argc, char *argv[]) ...@@ -30,6 +30,7 @@ int main(int argc, char *argv[])
oFrame.put_Data(pDataRaster); oFrame.put_Data(pDataRaster);
CFontManager* pManager = oFonts.GenerateFontManager(); CFontManager* pManager = oFonts.GenerateFontManager();
pManager->SetSubpixelRendering(true, false);
CImageFilesCache* pCache = new CImageFilesCache(); CImageFilesCache* pCache = new CImageFilesCache();
CGraphicsRenderer oRenderer; CGraphicsRenderer oRenderer;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment