The Painter now uses a special version of the agg_font_engine that uses the FontServer ftlib and the already loaded FT_Facees from ServerFont/FontStyle instead of doing it all again.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12177 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz
2005-03-31 06:08:37 +00:00
parent 37dd67fbd1
commit bb72ccac74
11 changed files with 152 additions and 209 deletions
+4 -11
View File
@@ -5,6 +5,8 @@
#include <Font.h>
#include <Rect.h>
#include <FontServer.h>
#include <ServerFont.h>
#include "defines.h"
#include "forwarding_pixfmt.h"
@@ -205,15 +207,6 @@ class Painter {
uint32 length,
const BPoint& baseLine) const;
// MISSING (?):
/*
// "screen blits"
void CopyBits( BRect src, BRect dst);
*/
private:
void _MakeEmpty();
@@ -228,7 +221,7 @@ class Painter {
void _RebuildClipping();
void _UpdateFont(const char* pathToFontFile = NULL);
void _UpdateFont();
void _UpdateLineWidth();
// drawing functions stroke/fill
@@ -306,7 +299,7 @@ class Painter {
BPoint fPenLocation;
PatternHandler* fPatternHandler;
BFont fFont;
ServerFont fFont;
// a class handling rendering and caching of glyphs
// it is setup to load from a specific Freetype supported
// font file, it uses the FontManager to locate a file
+3 -2
View File
@@ -76,8 +76,9 @@ AccelerantBuffer::Bits() const
if (InitCheck() != B_OK)
return NULL;
if (fFrameBufferConfig.frame_buffer_dma)
return fFrameBufferConfig.frame_buffer_dma;
// TODO: Enable this if we can ensure that frame_buffer_dma is valid
/*if (fFrameBufferConfig.frame_buffer_dma)
return fFrameBufferConfig.frame_buffer_dma;*/
return fFrameBufferConfig.frame_buffer;
}
@@ -241,8 +241,9 @@ AccelerantHWInterface::SetupDefaultHooks()
if (!fAccAcquireEngine || !fAccReleaseEngine || !fAccGetFrameBufferConfig
|| !fAccGetModeCount || !fAccGetModeList || !fAccSetDisplayMode
|| !fAccGetPixelClockLimits)
|| !fAccGetPixelClockLimits) {
return B_ERROR;
}
// optional
fAccGetTimingConstraints = (get_timing_constraints)fAccelerantHook(B_GET_TIMING_CONSTRAINTS, NULL);
@@ -331,7 +332,7 @@ AccelerantHWInterface::SetMode(const display_mode &mode)
// NOTE: backbuffer is always B_RGBA32, this simplifies the
// drawing backend implementation tremendously for the time
// being. The color space conversion is handled in CopyBackToFront()
BRect bounds(0, 0, fDisplayMode.virtual_width, fDisplayMode.virtual_height);
BRect bounds(0, 0, fDisplayMode.virtual_width - 1, fDisplayMode.virtual_height - 1);
BBitmap *backBitmap = new BBitmap(bounds, 0, B_RGBA32);
delete fBackBuffer;
@@ -504,6 +505,9 @@ AccelerantHWInterface::WaitForRetrace(bigtime_t timeout = B_INFINITE_TIMEOUT)
RenderingBuffer *
AccelerantHWInterface::FrontBuffer() const
{
if (!fModeList)
return NULL;
return fFrontBuffer;
}
@@ -511,6 +515,9 @@ AccelerantHWInterface::FrontBuffer() const
RenderingBuffer *
AccelerantHWInterface::BackBuffer() const
{
if (!fModeList)
return NULL;
return fBackBuffer;
}
+4 -2
View File
@@ -14,8 +14,10 @@ StaticLibrary painter :
drawing_modes/DrawingModeFactory.cpp
# is contained within libagg.a,
# but we might need a modified version later
# font_support/agg_font_freetype.cpp
# but we need a modified version that
# uses the FontServer
font_support/agg_font_freetype.cpp
font_support/AGGTextRenderer.cpp
font_support/FontManager.cpp
font_support/TextRenderer.cpp
+19 -32
View File
@@ -62,10 +62,12 @@ Painter::Painter()
fAlphaFncMode(B_ALPHA_OVERLAY),
fPenLocation(0.0, 0.0),
fPatternHandler(new PatternHandler()),
fFont(be_plain_font),
fTextRenderer(new AGGTextRenderer()),
fLastFamilyAndStyle(0)
{
if (fontserver)
fFont = *fontserver->GetSystemPlain();
_UpdateFont();
_UpdateLineWidth();
}
@@ -262,7 +264,12 @@ Painter::SetPenLocation(const BPoint& location)
void
Painter::SetFont(const BFont& font)
{
fFont = font;
//fFont.SetFamilyAndStyle(font.GetFamily(), font.GetStyle());
fFont.SetSpacing(font.Spacing());
fFont.SetShear(font.Shear());
fFont.SetRotation(font.Rotation());
fFont.SetSize(font.Size());
_UpdateFont();
}
@@ -270,18 +277,8 @@ Painter::SetFont(const BFont& font)
void
Painter::SetFont(const ServerFont& font)
{
// NOTE: this is just a transitional function
// to help integrate Painter with app_server later
fFont.SetFamilyAndStyle(font.GetFamily(), font.GetStyle());
fFont.SetSpacing(font.Spacing());
fFont.SetShear(font.Shear());
fFont.SetRotation(font.Rotation());
fFont.SetSize(font.Size());
if (fLastFamilyAndStyle != font.GetFamilyAndStyle()) {
fLastFamilyAndStyle = font.GetFamilyAndStyle();
_UpdateFont(font.GetPath());
}
fFont = font;
_UpdateFont();
}
// #pragma mark -
@@ -1052,27 +1049,17 @@ Painter::_RebuildClipping()
// _UpdateFont
void
Painter::_UpdateFont(const char* pathToFontFile)
Painter::_UpdateFont()
{
bool success = false;
if (pathToFontFile) {
success = fTextRenderer->SetFont(pathToFontFile);
if (fLastFamilyAndStyle != fFont.GetFamilyAndStyle()) {
fLastFamilyAndStyle = fFont.GetFamilyAndStyle();
bool success = false;
success = fTextRenderer->SetFont(fFont);
if (!success)
fprintf(stderr, "unable to set '%s'\n", pathToFontFile);
} else {
font_family family;
font_style style;
fFont.GetFamilyAndStyle(&family, &style);
fprintf(stderr, "unable to set font\n");
}
success = fTextRenderer->SetFamilyAndStyle(family, style);
if (!success)
fprintf(stderr, "unable to set '%s' + '%s'\n", family, style);
}
if (!success) {
fprintf(stderr, "font is still: '%s' + '%s'\n",
fTextRenderer->Family(), fTextRenderer->Style());
}
fTextRenderer->SetPointSize(fFont.Size());
}
@@ -4,6 +4,7 @@
#include <stdio.h>
#include <string.h>
#include <FontServer.h>
#include <Bitmap.h>
#include <ByteOrder.h>
#include <Entry.h>
@@ -45,7 +46,7 @@ rect_to_int(BRect r,
// constructor
AGGTextRenderer::AGGTextRenderer()
: TextRenderer(),
fFontEngine(),
fFontEngine(ftlib),
fFontManager(fFontEngine),
fCurves(fFontManager.path_adaptor()),
fContour(fCurves)
@@ -57,7 +58,7 @@ AGGTextRenderer::AGGTextRenderer()
AGGTextRenderer::AGGTextRenderer(BMessage* archive)
: TextRenderer(archive),
fFontEngine(),
fFontEngine(ftlib),
fFontManager(fFontEngine),
fCurves(fFontManager.path_adaptor()),
fContour(fCurves)
@@ -66,15 +67,12 @@ AGGTextRenderer::AGGTextRenderer(BMessage* archive)
fCurves.approximation_scale(2.0);
fContour.auto_detect_orientation(false);
fFontEngine.flip_y(true);
if (fFontFilePath)
SetFont(fFontFilePath);
}
// constructor
AGGTextRenderer::AGGTextRenderer(const AGGTextRenderer& from)
: TextRenderer(from),
fFontEngine(),
fFontEngine(ftlib),
fFontManager(fFontEngine),
fCurves(fFontManager.path_adaptor()),
fContour(fCurves)
@@ -82,9 +80,6 @@ AGGTextRenderer::AGGTextRenderer(const AGGTextRenderer& from)
fCurves.approximation_scale(2.0);
fContour.auto_detect_orientation(false);
fFontEngine.flip_y(true);
if (fFontFilePath)
SetFont(fFontFilePath);
}
// destructor
@@ -116,17 +111,13 @@ AGGTextRenderer::Archive(BMessage* into, bool deep) const
// SetFont
bool
AGGTextRenderer::SetFont(const char* pathToFontFile)
AGGTextRenderer::SetFont(const ServerFont &font)
{
if (pathToFontFile) {
if (fFontEngine.load_font(pathToFontFile, 0, agg::glyph_ren_outline)) {
// if (fFontEngine.load_font(pathToFontFile, 0, agg::glyph_ren_native_gray8)) {
return TextRenderer::SetFont(pathToFontFile);
} else {
fprintf(stderr, "%s : is not a font file or could not be opened\n",
pathToFontFile);
}
// if (fFontEngine.load_font(font, agg::glyph_ren_native_gray8)) {
if (fFontEngine.load_font(font, agg::glyph_ren_outline)) {
return TextRenderer::SetFont(font);
} else {
fprintf(stderr, "font could not be loaded\n");
}
return false;
}
@@ -11,6 +11,8 @@
#include "TextRenderer.h"
class ServerFont;
class AGGTextRenderer : public TextRenderer {
public:
AGGTextRenderer();
@@ -22,7 +24,7 @@ class AGGTextRenderer : public TextRenderer {
virtual status_t Archive(BMessage* into, bool deep = true) const;
virtual bool SetFont(const char* pathToFontFile);
virtual bool SetFont(const ServerFont &font);
virtual void Unset();
virtual const char* Family() const;
@@ -5,6 +5,7 @@
#include <Entry.h>
#include <Path.h>
#include <ServerFont.h>
#include "FontManager.h"
@@ -108,7 +109,7 @@ TextRenderer::SetTo(const TextRenderer* other)
fAdvanceScale = other->fAdvanceScale;
fLineSpacingScale = other->fLineSpacingScale;
SetFont(other->fFontFilePath);
strcpy(fFontFilePath, other->fFontFilePath);
Update();
}
@@ -148,26 +149,23 @@ TextRenderer::Archive(BMessage* into, bool deep) const
bool
TextRenderer::SetFontRef(const entry_ref* ref)
{
//printf("TextRenderer::SetFontRef(%s)\n", ref ? ref->name : "no ref!");
// TODO: Remove this, as we do font loading in FontServer
/*printf("TextRenderer::SetFontRef(%s)\n", ref ? ref->name : "no ref!");
if (ref) {
BPath path(ref);
if (path.InitCheck() >= B_OK)
return SetFont(path.Path());
}
return true;
}*/
return false;
}
// SetFont
bool
TextRenderer::SetFont(const char* pathToFontFile)
TextRenderer::SetFont(const ServerFont &font)
{
//printf("TextRenderer::SetFont(%s)\n", pathToFontFile ? pathToFontFile : "no path!");
if (pathToFontFile) {
sprintf(fFontFilePath, "%s", pathToFontFile);
//printf("font: %s\n", fFontFilePath);
return true;
}
return false;
sprintf(fFontFilePath, "%s", font.GetPath());
return true;
}
// Unset
@@ -8,6 +8,7 @@
struct entry_ref;
class BBitmap;
class ServerFont;
class TextRenderer : public BArchivable {
public:
@@ -21,7 +22,7 @@ class TextRenderer : public BArchivable {
virtual status_t Archive(BMessage* into, bool deep = true) const;
bool SetFontRef(const entry_ref* ref);
virtual bool SetFont(const char* pathToFontFile);
virtual bool SetFont(const ServerFont &font);
virtual void Unset();
bool SetFamilyAndStyle(const char* family,
@@ -19,6 +19,8 @@
#include "agg_bitset_iterator.h"
#include "agg_renderer_scanline.h"
#include <ServerFont.h>
#include <FontFamily.h>
namespace agg
{
@@ -412,27 +414,19 @@ namespace agg
//------------------------------------------------------------------------
font_engine_freetype_base::~font_engine_freetype_base()
{
unsigned i;
for(i = 0; i < m_num_faces; ++i)
{
delete [] m_face_names[i];
FT_Done_Face(m_faces[i]);
}
delete [] m_face_names;
delete [] m_face_ids;
delete [] m_faces;
delete [] m_signature;
if(m_library_initialized) FT_Done_FreeType(m_library);
}
//------------------------------------------------------------------------
font_engine_freetype_base::font_engine_freetype_base(bool flag32,
font_engine_freetype_base::font_engine_freetype_base(bool flag32, FT_Library library,
unsigned max_faces) :
m_flag32(flag32),
m_change_stamp(0),
m_last_error(0),
m_name(0),
m_name_len(256-16-1),
m_cur_id(0),
m_face_index(0),
m_char_map(FT_ENCODING_NONE),
m_signature(new char [256+256-16]),
@@ -440,10 +434,9 @@ namespace agg
m_width(0),
m_hinting(true),
m_flip_y(false),
m_library_initialized(false),
m_library(0),
m_library(library),
m_faces(new FT_Face [max_faces]),
m_face_names(new char* [max_faces]),
m_face_ids(new unsigned [max_faces]),
m_num_faces(0),
m_max_faces(max_faces),
m_cur_face(0),
@@ -472,8 +465,7 @@ namespace agg
m_matrix.yy = 0x10000L;
m_curves16.approximation_scale(4.0);
m_curves32.approximation_scale(4.0);
m_last_error = FT_Init_FreeType(&m_library);
if(m_last_error == 0) m_library_initialized = true;
m_last_error = 0;
}
@@ -487,120 +479,96 @@ namespace agg
//------------------------------------------------------------------------
int font_engine_freetype_base::find_face(const char* face_name) const
int font_engine_freetype_base::find_face(unsigned face_id) const
{
unsigned i;
for(i = 0; i < m_num_faces; ++i)
{
if(strcmp(face_name, m_face_names[i]) == 0) return i;
if(m_face_ids[i] == face_id) return i;
}
return -1;
}
//------------------------------------------------------------------------
bool font_engine_freetype_base::load_font(const char* font_name,
unsigned face_index,
bool font_engine_freetype_base::load_font(const ServerFont &font,
glyph_rendering ren_type)
{
bool ret = false;
bool ret = false;
if(m_library_initialized)
m_last_error = 0;
int idx = find_face(font.GetFamilyAndStyle());
if(idx >= 0)
{
m_last_error = 0;
int idx = find_face(font_name);
if(idx >= 0)
m_cur_face = m_faces[idx];
m_cur_id = m_face_ids[idx];
}
else
{
if(m_num_faces >= m_max_faces)
{
m_cur_face = m_faces[idx];
m_name = m_face_names[idx];
memcpy(m_faces,
m_faces + 1,
(m_max_faces - 1) * sizeof(FT_Face));
memcpy(m_face_ids,
m_face_ids + 1,
(m_max_faces - 1) * sizeof(unsigned));
m_num_faces = m_max_faces - 1;
}
else
{
if(m_num_faces >= m_max_faces)
{
delete [] m_face_names[0];
FT_Done_Face(m_faces[0]);
memcpy(m_faces,
m_faces + 1,
(m_max_faces - 1) * sizeof(FT_Face));
memcpy(m_face_names,
m_face_names + 1,
(m_max_faces - 1) * sizeof(char*));
m_num_faces = m_max_faces - 1;
}
m_last_error = FT_New_Face(m_library,
font_name,
face_index,
&m_faces[m_num_faces]);
if(m_last_error == 0)
m_faces[m_num_faces] = font.GetFTFace();
m_face_ids[m_num_faces] = font.GetFamilyAndStyle();
m_cur_face = m_faces[m_num_faces];
m_cur_id = m_face_ids[m_num_faces];
++m_num_faces;
}
if(m_last_error == 0)
{
ret = true;
switch(ren_type)
{
case glyph_ren_native_mono:
m_glyph_rendering = glyph_ren_native_mono;
break;
case glyph_ren_native_gray8:
m_glyph_rendering = glyph_ren_native_gray8;
break;
case glyph_ren_outline:
if(FT_IS_SCALABLE(m_cur_face))
{
m_face_names[m_num_faces] = new char [strlen(font_name) + 1];
strcpy(m_face_names[m_num_faces], font_name);
m_cur_face = m_faces[m_num_faces];
m_name = m_face_names[m_num_faces];
++m_num_faces;
m_glyph_rendering = glyph_ren_outline;
}
else
{
m_face_names[m_num_faces] = 0;
m_cur_face = 0;
m_name = 0;
}
}
if(m_last_error == 0)
{
ret = true;
switch(ren_type)
{
case glyph_ren_native_mono:
m_glyph_rendering = glyph_ren_native_mono;
break;
case glyph_ren_native_gray8:
m_glyph_rendering = glyph_ren_native_gray8;
break;
case glyph_ren_outline:
if(FT_IS_SCALABLE(m_cur_face))
{
m_glyph_rendering = glyph_ren_outline;
}
else
{
m_glyph_rendering = glyph_ren_native_gray8;
}
break;
case glyph_ren_agg_mono:
if(FT_IS_SCALABLE(m_cur_face))
{
m_glyph_rendering = glyph_ren_agg_mono;
}
else
{
m_glyph_rendering = glyph_ren_native_mono;
}
break;
case glyph_ren_agg_gray8:
if(FT_IS_SCALABLE(m_cur_face))
{
m_glyph_rendering = glyph_ren_agg_gray8;
}
else
{
m_glyph_rendering = glyph_ren_native_gray8;
}
break;
}
update_transform();
break;
case glyph_ren_agg_mono:
if(FT_IS_SCALABLE(m_cur_face))
{
m_glyph_rendering = glyph_ren_agg_mono;
}
else
{
m_glyph_rendering = glyph_ren_native_mono;
}
break;
case glyph_ren_agg_gray8:
if(FT_IS_SCALABLE(m_cur_face))
{
m_glyph_rendering = glyph_ren_agg_gray8;
}
else
{
m_glyph_rendering = glyph_ren_native_gray8;
}
break;
}
update_transform();
}
return ret;
}
@@ -738,16 +706,8 @@ namespace agg
//------------------------------------------------------------------------
void font_engine_freetype_base::update_signature()
{
if(m_cur_face && m_name)
if(m_cur_face)
{
unsigned name_len = strlen(m_name);
if(name_len > m_name_len)
{
delete [] m_signature;
m_signature = new char [name_len + 32 + 256];
m_name_len = name_len + 32 - 1;
}
unsigned gamma_hash = 0;
if(m_glyph_rendering == glyph_ren_native_gray8 ||
m_glyph_rendering == glyph_ren_agg_mono ||
@@ -763,8 +723,8 @@ namespace agg
}
sprintf(m_signature,
"%s,%u,%d,%d,%d:%dx%d,%d,%d,%d,%d,%d,%d,%08X",
m_name,
"%u,%u,%d,%d,%d:%dx%d,%d,%d,%d,%d,%d,%d,%08X",
m_cur_id,
m_char_map,
m_face_index,
int(m_glyph_rendering),
@@ -34,6 +34,8 @@
#include "agg_trans_affine.h"
#include "agg_font_cache_manager.h"
class ServerFont;
namespace agg
{
@@ -50,12 +52,12 @@ namespace agg
//--------------------------------------------------------------------
~font_engine_freetype_base();
font_engine_freetype_base(bool flag32, unsigned max_faces = 32);
font_engine_freetype_base(bool flag32, FT_Library library, unsigned max_faces = 32);
// Set font parameters
//--------------------------------------------------------------------
void resolution(unsigned dpi);
bool load_font(const char* font_name, unsigned face_index, glyph_rendering ren_type);
bool load_font(const ServerFont &font, glyph_rendering ren_type);
bool attach(const char* file_name);
bool char_map(FT_Encoding map);
bool height(double h);
@@ -76,7 +78,7 @@ namespace agg
//--------------------------------------------------------------------
int last_error() const { return m_last_error; }
unsigned resolution() const { return m_resolution; }
const char* name() const { return m_name; }
unsigned cur_id() const { return m_cur_id; }
unsigned num_faces() const;
FT_Encoding char_map() const { return m_char_map; }
double height() const { return double(m_height) / 64.0; }
@@ -108,13 +110,12 @@ namespace agg
void update_char_size();
void update_signature();
void update_transform();
int find_face(const char* face_name) const;
int find_face(unsigned face_id) const;
bool m_flag32;
int m_change_stamp;
int m_last_error;
char* m_name;
unsigned m_name_len;
unsigned m_cur_id;
unsigned m_face_index;
FT_Encoding m_char_map;
char* m_signature;
@@ -126,7 +127,7 @@ namespace agg
bool m_library_initialized;
FT_Library m_library; // handle to library
FT_Face* m_faces; // A pool of font faces
char** m_face_names;
unsigned* m_face_ids;
unsigned m_num_faces;
unsigned m_max_faces;
FT_Face m_cur_face; // handle to the current face object
@@ -167,8 +168,8 @@ namespace agg
typedef font_engine_freetype_base::scanlines_aa_type scanlines_aa_type;
typedef font_engine_freetype_base::scanlines_bin_type scanlines_bin_type;
font_engine_freetype_int16(unsigned max_faces = 32) :
font_engine_freetype_base(false, max_faces) {}
font_engine_freetype_int16(FT_Library library, unsigned max_faces = 32) :
font_engine_freetype_base(false, library, max_faces) {}
};
//------------------------------------------------font_engine_freetype_int32
@@ -185,8 +186,8 @@ namespace agg
typedef font_engine_freetype_base::scanlines_aa_type scanlines_aa_type;
typedef font_engine_freetype_base::scanlines_bin_type scanlines_bin_type;
font_engine_freetype_int32(unsigned max_faces = 32) :
font_engine_freetype_base(true, max_faces) {}
font_engine_freetype_int32(FT_Library library, unsigned max_faces = 32) :
font_engine_freetype_base(true, library, max_faces) {}
};