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

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

parent 9fa776d1
......@@ -153,6 +153,21 @@ namespace agg
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));
}
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
......@@ -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,
......
......@@ -281,6 +281,28 @@ namespace agg
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,
const color_type& c,
......
......@@ -149,6 +149,16 @@ namespace agg
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:
base_ren_type* m_ren;
......
......@@ -1177,7 +1177,7 @@ INT CFontFile::GetString2(CGlyphString& oString)
oSizes.oMetrics.fWidth = (float)(pFace->glyph->metrics.width >> 6);
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;
TGlyphBitmap *pBitmap = &(pCurGlyph->oBitmap);
......@@ -1457,7 +1457,7 @@ INT CFontFile::GetString2C(CGlyphString& oString)
oSizes.oMetrics.fWidth = (float)(pFace->glyph->metrics.width >> 6);
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;
TGlyphBitmap *pBitmap = &(pCurGlyph->oBitmap);
......
......@@ -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 REND_MODE FT_RENDER_MODE_NORMAL
#define FONT_ITALIC_ANGLE 0.3090169943749 // Синус 18 градусов (подбиралось под Word 2007)
......
......@@ -2,6 +2,7 @@
#include "../common/File.h"
#include <stdio.h>
#include "ftsnames.h"
#include FT_LCD_FILTER_H
///////////////////////////////////////////////////////////////////////////////////////////////////////
CFontStream::CFontStream()
......@@ -205,6 +206,7 @@ CFontManager::CFontManager()
{
m_pLibrary = NULL;
FT_Init_FreeType(&m_pLibrary);
FT_Library_SetLcdFilter(m_pLibrary, FT_LCD_FILTER_DEFAULT);
m_pFont = NULL;
m_pApplication = NULL;
......@@ -214,6 +216,8 @@ CFontManager::CFontManager()
m_nLOAD_MODE = 40968;
m_lRef = 1;
m_nRENDER_MODE = FT_RENDER_MODE_NORMAL;
m_bUseDefaultFont = FALSE;
m_fCharSpacing = 0;
......@@ -704,3 +708,13 @@ unsigned int CFontManager::GetNameIndex(const std::wstring& wsName) const
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:
int m_lLineHeight;
int m_nLOAD_MODE;
int m_nRENDER_MODE;
CApplicationFonts* m_pApplication;
CFontsCache* m_pOwnerCache;
......@@ -169,6 +170,8 @@ public:
std::wstring GetFontType() const;
unsigned int GetNameIndex(const std::wstring& wsName) const;
void SetSubpixelRendering(const bool& hmul, const bool& vmul);
public:
static CFontFile* LoadFontFile(FT_Library library, CFontStream* pStream, LONG lFaceIndex);
......
......@@ -92,7 +92,7 @@ FT_BEGIN_HEADER
/* This is done to allow FreeType clients to run unmodified, forcing */
/* 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 <algorithm>
#include "../fontengine/FontFile.h"
namespace Aggplus
{
......@@ -33,6 +34,8 @@ namespace Aggplus
#endif
m_dDpiTile = -1;
m_nTextRenderMode = FT_RENDER_MODE_NORMAL;
}
CGraphics::CGraphics(int dwWidth, int dwHeight, int stride, BYTE* pBuffer) : m_dwConfigFlags(0)
......@@ -968,6 +971,7 @@ namespace Aggplus
oM1.TransformPoint(_x, _y);
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);
float fX = 0;
......@@ -1012,6 +1016,7 @@ namespace Aggplus
oM1.TransformPoint(_x, _y);
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);
float fX = 0;
......@@ -1902,7 +1907,15 @@ namespace Aggplus
typedef agg::renderer_scanline_aa_solid<base_renderer_type> solid_renderer_type;
solid_renderer_type ren_fine(m_frame_buffer.ren_base());
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;
}
......
......@@ -15,7 +15,7 @@ int main(int argc, char *argv[])
double dWidthMM = 25.4 * nRasterW / 96;
double dHeightMM = 25.4 * nRasterH / 96;
if (true)
if (false)
{
nRasterW *= 2;
nRasterH *= 2;
......@@ -30,6 +30,7 @@ int main(int argc, char *argv[])
oFrame.put_Data(pDataRaster);
CFontManager* pManager = oFonts.GenerateFontManager();
pManager->SetSubpixelRendering(true, false);
CImageFilesCache* pCache = new CImageFilesCache();
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