diff --git a/src/servers/app/drawing/AccelerantHWInterface.cpp b/src/servers/app/drawing/AccelerantHWInterface.cpp index 8fbab26e37..713a453290 100644 --- a/src/servers/app/drawing/AccelerantHWInterface.cpp +++ b/src/servers/app/drawing/AccelerantHWInterface.cpp @@ -586,7 +586,8 @@ AccelerantHWInterface::ProposeMode(display_mode *candidate, const display_mode * sem_id AccelerantHWInterface::RetraceSemaphore() { - accelerant_retrace_semaphore AccelerantRetraceSemaphore = (accelerant_retrace_semaphore)fAccelerantHook(B_ACCELERANT_RETRACE_SEMAPHORE, NULL); + accelerant_retrace_semaphore AccelerantRetraceSemaphore = + (accelerant_retrace_semaphore)fAccelerantHook(B_ACCELERANT_RETRACE_SEMAPHORE, NULL); if (!AccelerantRetraceSemaphore) return B_UNSUPPORTED; diff --git a/src/servers/app/drawing/DrawingEngine.cpp b/src/servers/app/drawing/DrawingEngine.cpp index fa616d3e7b..af6a98639a 100644 --- a/src/servers/app/drawing/DrawingEngine.cpp +++ b/src/servers/app/drawing/DrawingEngine.cpp @@ -997,9 +997,10 @@ DrawingEngine::DrawString(const char* string, int32 length, escapement_delta* delta) { // TODO: use delta + FontLocker locker(d); + BPoint penLocation = pt; if (Lock()) { - FontLocker locker(d); fPainter->SetDrawState(d, true); //bigtime_t now = system_time(); // TODO: BoundingBox is quite slow!! Optimizing it will be beneficial. @@ -1034,6 +1035,8 @@ DrawingEngine::StringWidth(const char* string, int32 length, const DrawState* d, escapement_delta* delta) { // TODO: use delta + FontLocker locker(d); + float width = 0.0; // if (Lock()) { // NOTE: For now it is enough to block on the @@ -1042,7 +1045,6 @@ DrawingEngine::StringWidth(const char* string, int32 length, // deadlock in case another thread holds the font // lock already and then tries to lock the drawing // engine after it is already locked here (race condition) - FontLocker locker(d); width = fPainter->StringWidth(string, length, d); // Unlock(); // } @@ -1054,7 +1056,6 @@ float DrawingEngine::StringWidth(const char* string, int32 length, const ServerFont& font, escapement_delta* delta) { - FontLocker locker(&font); DrawState d; d.SetFont(font); return StringWidth(string, length, &d, delta); @@ -1065,6 +1066,8 @@ float DrawingEngine::StringHeight(const char *string, int32 length, const DrawState *d) { + FontLocker locker(d); + float height = 0.0; // if (Lock()) { // NOTE: For now it is enough to block on the @@ -1073,7 +1076,6 @@ DrawingEngine::StringHeight(const char *string, int32 length, // deadlock in case another thread holds the font // lock already and then tries to lock the drawing // engine after it is already locked here (race condition) - FontLocker locker(d); fPainter->SetDrawState(d, true); BPoint dummy1(0.0, 0.0); BPoint dummy2(0.0, 0.0); diff --git a/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.cpp b/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.cpp index e3091fb815..e50307976f 100644 --- a/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.cpp +++ b/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.cpp @@ -83,12 +83,7 @@ AGGTextRenderer::AGGTextRenderer() fHinted(true), fAntialias(true), fKerning(true), - fEmbeddedTransformation(), - - fFont(), - fLastFamilyAndStyle(0xffffffff), - fLastPointSize(-1.0), - fLastHinted(false) + fEmbeddedTransformation() { fCurves.approximation_scale(2.0); fContour.auto_detect_orientation(false); @@ -106,37 +101,19 @@ AGGTextRenderer::~AGGTextRenderer() bool AGGTextRenderer::SetFont(const ServerFont &font) { - bool success = true; // construct an embedded transformation (rotate & shear) - Transformable transform; - transform.ShearBy(B_ORIGIN, (90.0 - font.Shear()) * PI / 180.0, 0.0); - transform.RotateBy(B_ORIGIN, -font.Rotation() * PI / 180.0); + fEmbeddedTransformation.Reset(); + fEmbeddedTransformation.ShearBy(B_ORIGIN, + (90.0 - font.Shear()) * PI / 180.0, 0.0); + fEmbeddedTransformation.RotateBy(B_ORIGIN, + -font.Rotation() * PI / 180.0); - bool load = font.GetFamilyAndStyle() != fLastFamilyAndStyle || - transform != fEmbeddedTransformation; + agg::glyph_rendering glyphType = + fHinted && fEmbeddedTransformation.IsIdentity() ? + agg::glyph_ren_native_gray8 : + agg::glyph_ren_outline; - if (load) { - if (transform.IsIdentity()) { - success = fFontEngine.load_font(font, agg::glyph_ren_native_gray8); -//printf("AGGTextRenderer::SetFont() - native: %d\n", success); - } else { - success = fFontEngine.load_font(font, agg::glyph_ren_outline); -//printf("AGGTextRenderer::SetFont() - outline: %d\n", success); - } -// } else { -//printf("AGGTextRenderer::SetFont() - already loaded\n"); - } - - fLastFamilyAndStyle = font.GetFamilyAndStyle(); - fEmbeddedTransformation = transform; - fFont = font; - - _UpdateSizeAndHinting(font.Size(), fEmbeddedTransformation.IsIdentity() && fHinted, load); - - if (!success) { - fprintf(stderr, "font could not be loaded\n"); - return false; - } + fFontEngine.load_font(font, glyphType, font.Size()); return true; } @@ -145,10 +122,8 @@ AGGTextRenderer::SetFont(const ServerFont &font) void AGGTextRenderer::SetHinting(bool hinting) { - if (fHinted != hinting) { - fHinted = hinting; - _UpdateSizeAndHinting(fLastPointSize, fEmbeddedTransformation.IsIdentity() && fHinted); - } + fHinted = hinting; + fFontEngine.hinting(fEmbeddedTransformation.IsIdentity() && fHinted); } // SetAntialiasing @@ -214,6 +189,8 @@ AGGTextRenderer::RenderString(const char* string, BPoint transformOffset(0.0, 0.0); transform.Transform(&transformOffset); + fFontCache.reset(); + uint32 charCode; while ((charCode = UTF8ToCharCode(&string)) > 0) { // line break (not supported by R5) @@ -370,6 +347,8 @@ AGGTextRenderer::StringWidth(const char* string, uint32 length) const agg::glyph_cache* glyph; bool firstLoop = true; + fFontCache.reset(); + while ((charCode = UTF8ToCharCode(&string)) > 0) { glyph = fFontCache.glyph(charCode); if (glyph) { @@ -384,18 +363,3 @@ AGGTextRenderer::StringWidth(const char* string, uint32 length) return width; } -// _UpdateSizeAndHinting -void -AGGTextRenderer::_UpdateSizeAndHinting(float size, bool hinted, bool force) -{ - if (force || size != fLastPointSize || hinted != fLastHinted) { -//printf("AGGTextRenderer::_UpdateSizeAndHinting(%.1f, %d, %d)\n", size, hinted, force); - fLastPointSize = size; - fLastHinted = hinted; - - fFontEngine.height(size); - fFontEngine.width(size); - fFontEngine.hinting(hinted); - } -} - diff --git a/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.h b/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.h index 3c8c5e452c..7e334471cb 100644 --- a/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.h +++ b/src/servers/app/drawing/Painter/font_support/AGGTextRenderer.h @@ -50,9 +50,6 @@ class AGGTextRenderer { uint32 length); private: - void _UpdateSizeAndHinting(float size, bool hinted, - bool force = false); - typedef agg::font_engine_freetype_int32 font_engine_type; typedef agg::font_cache_manager font_cache_type; @@ -79,12 +76,6 @@ class AGGTextRenderer { bool fAntialias; bool fKerning; Transformable fEmbeddedTransformation; // rotated or sheared font? - - // caching to avoid loading a font unnecessarily - ServerFont fFont; - uint32 fLastFamilyAndStyle; - float fLastPointSize; - bool fLastHinted; }; #endif // AGG_TEXT_RENDERER_H diff --git a/src/servers/app/drawing/Painter/font_support/agg_font_freetype.cpp b/src/servers/app/drawing/Painter/font_support/agg_font_freetype.cpp index f03253ad4d..a593b585b1 100644 --- a/src/servers/app/drawing/Painter/font_support/agg_font_freetype.cpp +++ b/src/servers/app/drawing/Painter/font_support/agg_font_freetype.cpp @@ -113,19 +113,19 @@ namespace agg { //------------------------------------------------------------------------------ - static unsigned calc_crc32(const unsigned char* buf, unsigned size) - { - unsigned crc = (unsigned)~0; - const unsigned char* p; - unsigned len = 0; - unsigned nr = size; - - for (len += nr, p = buf; nr--; ++p) - { - crc = (crc >> 8) ^ crc32tab[(crc ^ *p) & 0xff]; - } - return ~crc; - } +// static unsigned calc_crc32(const unsigned char* buf, unsigned size) +// { +// unsigned crc = (unsigned)~0; +// const unsigned char* p; +// unsigned len = 0; +// unsigned nr = size; +// +// for (len += nr, p = buf; nr--; ++p) +// { +// crc = (crc >> 8) ^ crc32tab[(crc ^ *p) & 0xff]; +// } +// return ~crc; +// } //------------------------------------------------------------------------ @@ -417,7 +417,7 @@ namespace agg { //------------------------------------------------------------------------ font_engine_freetype_base::~font_engine_freetype_base() { - delete [] m_face_ids; +// delete [] m_face_ids; delete [] m_signature; } @@ -432,14 +432,13 @@ namespace agg { m_face_index(0), m_char_map(FT_ENCODING_NONE), m_signature(new char [256+256-16]), - m_height(0), - m_width(0), + m_size(0), m_hinting(true), m_flip_y(false), m_library(library), - m_face_ids(new unsigned [max_faces]), - m_num_faces(0), - m_max_faces(max_faces), +// m_face_ids(new unsigned [max_faces]), +// m_num_faces(0), +// m_max_faces(max_faces), m_cur_face(0), m_resolution(0), m_glyph_rendering(glyph_ren_native_gray8), @@ -479,96 +478,60 @@ namespace agg { } - //------------------------------------------------------------------------ - int font_engine_freetype_base::find_face(unsigned face_id) const - { - unsigned i; - for(i = 0; i < m_num_faces; ++i) - { - if(m_face_ids[i] == face_id) return i; - } - return -1; - } - - //------------------------------------------------------------------------ bool font_engine_freetype_base::load_font(const ServerFont &font, - glyph_rendering ren_type) + glyph_rendering ren_type, + double size) { - bool ret = false; + if (m_cur_face == font.GetFTFace() + && m_cur_id == font.GetFamilyAndStyle() + && m_glyph_rendering == ren_type + && m_size == unsigned(size * 64.0)) { + // make sure the freetype lib is in sync too + FT_Set_Pixel_Sizes(m_cur_face, + m_size >> 6, // pixel_width + m_size >> 6); // pixel_height + return true; + } - m_last_error = 0; + m_cur_face = font.GetFTFace(); + m_cur_id = font.GetFamilyAndStyle(); - int idx = find_face(font.GetFamilyAndStyle()); - if(idx >= 0) - { - m_cur_face = font.GetFTFace(); - m_cur_id = m_face_ids[idx]; - } - else - { - if(m_num_faces >= m_max_faces) - { - memcpy(m_face_ids, - m_face_ids + 1, - (m_max_faces - 1) * sizeof(unsigned)); - m_num_faces = m_max_faces - 1; - } + m_size = unsigned(size * 64.0); - m_face_ids[m_num_faces] = font.GetFamilyAndStyle(); - m_cur_face = font.GetFTFace(); - m_cur_id = m_face_ids[m_num_faces]; - ++m_num_faces; + switch(ren_type) { + case glyph_ren_native_mono: + m_glyph_rendering = glyph_ren_native_mono; + break; + case glyph_ren_native_gray8: + m_hinting = true; + 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; } - 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(); - update_char_size(); - } - return ret; +// NOTE: Freetype (embedded) transformation not used +// (and it would result in update_signature() being called twice +// update_transform(); + update_char_size(); + return true; } @@ -609,21 +572,9 @@ namespace agg { } //------------------------------------------------------------------------ - bool font_engine_freetype_base::height(double h) + bool font_engine_freetype_base::size(double size) { - m_height = int(h * 64.0); - if(m_cur_face) - { - update_char_size(); - return true; - } - return false; - } - - //------------------------------------------------------------------------ - bool font_engine_freetype_base::width(double w) - { - m_width = int(w * 64.0); + m_size = int(size * 64.0); if(m_cur_face) { update_char_size(); @@ -684,11 +635,14 @@ namespace agg { //------------------------------------------------------------------------ void font_engine_freetype_base::hinting(bool h) { - m_hinting = h; - if(m_cur_face) - { - update_signature(); - } + if(m_hinting != h) + { + m_hinting = h; + if(m_cur_face) + { + update_signature(); + } + } } //------------------------------------------------------------------------ @@ -706,36 +660,46 @@ namespace agg { { if(m_cur_face) { - unsigned gamma_hash = 0; - if(m_glyph_rendering == glyph_ren_native_gray8 || - m_glyph_rendering == glyph_ren_agg_mono || - m_glyph_rendering == glyph_ren_agg_gray8) - { - unsigned char gamma_table[rasterizer_scanline_aa<>::aa_num]; - unsigned i; - for(i = 0; i < rasterizer_scanline_aa<>::aa_num; ++i) - { - gamma_table[i] = m_rasterizer.apply_gamma(i); - } - gamma_hash = calc_crc32(gamma_table, sizeof(gamma_table)); - } - +// NOTE: gamma is fixed for now, so no need to switch +// font cache based on gamma +// unsigned gamma_hash = 0; +// if(m_glyph_rendering == glyph_ren_native_gray8 || +// m_glyph_rendering == glyph_ren_agg_mono || +// m_glyph_rendering == glyph_ren_agg_gray8) +// { +// unsigned char gamma_table[rasterizer_scanline_aa<>::aa_num]; +// unsigned i; +// for(i = 0; i < rasterizer_scanline_aa<>::aa_num; ++i) +// { +// gamma_table[i] = m_rasterizer.apply_gamma(i); +// } +// gamma_hash = calc_crc32(gamma_table, sizeof(gamma_table)); +// } +// +// sprintf(m_signature, +// "%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), +// m_resolution, +// m_height, +// m_width, +// int(m_matrix.xx), +// int(m_matrix.xy), +// int(m_matrix.yx), +// int(m_matrix.yy), +// int(m_hinting), +// int(m_flip_y), +// gamma_hash); sprintf(m_signature, - "%u,%u,%d,%d,%d:%dx%d,%d,%d,%d,%d,%d,%d,%08X", + "%u,%u,%d,%d,%d,%d", m_cur_id, m_char_map, m_face_index, int(m_glyph_rendering), - m_resolution, - m_height, - m_width, - int(m_matrix.xx), - int(m_matrix.xy), - int(m_matrix.yx), - int(m_matrix.yy), - int(m_hinting), - int(m_flip_y), - gamma_hash); + m_size, + int(m_hinting)); ++m_change_stamp; } } @@ -749,16 +713,16 @@ namespace agg { if(m_resolution) { FT_Set_Char_Size(m_cur_face, - m_width, // char_width in 1/64th of points - m_height, // char_height in 1/64th of points + m_size, // char_width in 1/64th of points + m_size, // char_height in 1/64th of points m_resolution, // horizontal device resolution m_resolution); // vertical device resolution } else { FT_Set_Pixel_Sizes(m_cur_face, - m_width >> 6, // pixel_width - m_height >> 6); // pixel_height + m_size >> 6, // pixel_width + m_size >> 6); // pixel_height } update_signature(); } diff --git a/src/servers/app/drawing/Painter/font_support/agg_font_freetype.h b/src/servers/app/drawing/Painter/font_support/agg_font_freetype.h index 9d078fb6f8..ce1e2402d8 100644 --- a/src/servers/app/drawing/Painter/font_support/agg_font_freetype.h +++ b/src/servers/app/drawing/Painter/font_support/agg_font_freetype.h @@ -57,11 +57,11 @@ namespace agg // Set font parameters //-------------------------------------------------------------------- void resolution(unsigned dpi); - bool load_font(const ServerFont &font, glyph_rendering ren_type); + bool load_font(const ServerFont &font, glyph_rendering ren_type, + double size); bool attach(const char* file_name); bool char_map(FT_Encoding map); - bool height(double h); - bool width(double w); + bool size(double size); void transform(const trans_affine& mtx); void transform(double xx, double xy, double yx, double yy); void hinting(bool h); @@ -81,8 +81,7 @@ namespace agg 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; } - double width() const { return double(m_width) / 64.0; } + double size() const { return double(m_size) / 64.0; } bool hinting() const { return m_hinting; } bool flip_y() const { return m_flip_y; } @@ -110,7 +109,6 @@ namespace agg void update_char_size(); void update_signature(); void update_transform(); - int find_face(unsigned face_id) const; bool m_flag32; int m_change_stamp; @@ -119,16 +117,12 @@ namespace agg unsigned m_face_index; FT_Encoding m_char_map; char* m_signature; - unsigned m_height; - unsigned m_width; + unsigned m_size; FT_Matrix m_matrix; bool m_hinting; bool m_flip_y; bool m_library_initialized; FT_Library m_library; // handle to library - unsigned* m_face_ids; - unsigned m_num_faces; - unsigned m_max_faces; FT_Face m_cur_face; // handle to the current face object int m_resolution; glyph_rendering m_glyph_rendering;