forked from celiagg/celiagg
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Make the font cache a separate object (celiagg#74)
This is a rather sizable refactor which aims to fix the [Windows] text rendering bugs introduced in PR celiagg#65. Instead of creating `thread_local` globals in `Font` for management of glyph caching, I've separated out the font cache into a new `FontCache` object which exists independently of the `Canvas*` and `Font` objects. A font cache can be shared between any number of canvas instances, as long as one takes care not to use the cache simultaneously from multiple threads. One big downside of this change is that it **breaks** the existing `Font` API by moving the `Font.string_width` method to `FontCache.width`. Therefore I intend to bump the package's major version number to 2, as an extra warning to downstream users. `Canvas*` classes also need to be passed a `FontCache` instance at construction time, but existing code can continue to work _without modification_ due to some Python wrappers in the package's `__init__` module.
- Loading branch information
Showing
29 changed files
with
795 additions
and
343 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
# The MIT License (MIT) | ||
# | ||
# Copyright (c) 2014-2016 WUSTL ZPLAB | ||
# Copyright (c) 2016-2021 Celiagg Contributors | ||
# | ||
# Permission is hereby granted, free of charge, to any person obtaining a copy | ||
# of this software and associated documentation files (the "Software"), to deal | ||
|
@@ -23,16 +24,113 @@ | |
# Authors: Erik Hvatum <[email protected]> | ||
# John Wiggins <[email protected]> | ||
|
||
# flake8: noqa | ||
from __future__ import absolute_import | ||
|
||
from ._celiagg import HAS_TEXT | ||
from . import _celiagg | ||
from ._celiagg import ( | ||
AggError, BlendMode, BSpline, DrawingMode, Font, FontCacheType, | ||
AggError, BSpline, BlendMode, DrawingMode, Font, FontCache, FontCacheType, | ||
GradientSpread, GradientUnits, GraphicsState, Image, InnerJoin, | ||
LinearGradientPaint, LineCap, LineJoin, RadialGradientPaint, Path, | ||
PatternPaint, PatternStyle, PixelFormat, Rect, ShapeAtPoints, SolidPaint, | ||
TextDrawingMode, Transform | ||
LineCap, LineJoin, LinearGradientPaint, Path, PatternPaint, PatternStyle, | ||
PixelFormat, RadialGradientPaint, Rect, ShapeAtPoints, SolidPaint, | ||
TextDrawingMode, Transform, | ||
) | ||
|
||
# Query the library | ||
HAS_TEXT = _celiagg.has_text_rendering() | ||
|
||
# Be explicit | ||
__all__ = [ | ||
'HAS_TEXT', | ||
|
||
'AggError', 'BlendMode', 'BSpline', 'DrawingMode', 'Font', 'FontCache', | ||
'FontCacheType', 'GradientSpread', 'GradientUnits', 'GraphicsState', | ||
'Image', 'InnerJoin', 'LinearGradientPaint', 'LineCap', 'LineJoin', | ||
'RadialGradientPaint', 'Path', 'PatternPaint', 'PatternStyle', | ||
'PixelFormat', 'Rect', 'ShapeAtPoints', 'SolidPaint', 'TextDrawingMode', | ||
'Transform', | ||
|
||
'CanvasG8', 'CanvasGA16', 'CanvasRGB24', 'CanvasRGBA32', 'CanvasBGRA32', | ||
'CanvasRGBA128', | ||
] | ||
|
||
# Keep a font cache for callers that don't want to mess with it | ||
__global_font_cache = None | ||
|
||
_canvas_doc_string = """{klass_name}(array, bottom_up=False, font_cache=None) | ||
Provides AGG (Anti-Grain Geometry) drawing routines that render to the | ||
numpy array passed as the constructor argument. Because this array is | ||
modified in place, it must be of type ``{array_type}``, must be | ||
C-contiguous, and must be {channel_desc}. | ||
:param array: A ``{array_type}`` array with shape {array_shape}. | ||
:param bottom_up: If True, the origin is the bottom left, instead of top-left | ||
:param font_cache: A ``FontCache`` instance. Defaults to a global instance. | ||
""" | ||
|
||
|
||
def _use_global_cache(): | ||
""" Return the global ``FontCache`` instance. | ||
""" | ||
global __global_font_cache | ||
if __global_font_cache is None: | ||
__global_font_cache = FontCache() | ||
return __global_font_cache | ||
|
||
|
||
def _build_canvas_factory(klass_name, array_type, array_shape, channel_desc): | ||
""" Generate a Canvas factory. | ||
This is done to preserve the v1.0.0 interface of canvas class constructors. | ||
Using these factory functions keeps the ``font_cache`` parameter optional. | ||
""" | ||
klass = getattr(_celiagg, klass_name) | ||
|
||
def factory(array, bottom_up=False, font_cache=None): | ||
cache = _use_global_cache() if font_cache is None else font_cache | ||
return klass(array, cache, bottom_up=bottom_up) | ||
|
||
factory.__doc__ = _canvas_doc_string.format( | ||
klass_name=klass_name, | ||
array_type=array_type, | ||
array_shape=array_shape, | ||
channel_desc=channel_desc, | ||
) | ||
factory.__name__ = klass_name | ||
return factory | ||
|
||
|
||
# Generate the canvas classes | ||
CanvasG8 = _build_canvas_factory( | ||
'CanvasG8', | ||
'numpy.uint8', | ||
'(H, W)', | ||
'MxN (1 channel: intensity)', | ||
) | ||
CanvasGA16 = _build_canvas_factory( | ||
'CanvasGA16', | ||
'numpy.uint8', | ||
'(H, W, 2)', | ||
'MxNx2 (2 channels: intensity and alpha)', | ||
) | ||
CanvasRGB24 = _build_canvas_factory( | ||
'CanvasRGB24', | ||
'numpy.uint8', | ||
'(H, W, 3', | ||
'MxNx3 (3 channels: red, green, and blue)', | ||
) | ||
CanvasRGBA32 = _build_canvas_factory( | ||
'CanvasRGBA32', | ||
'numpy.uint8', | ||
'(H, W, 4)', | ||
'MxNx4 (4 channels: red, green, blue, and alpha)', | ||
) | ||
CanvasBGRA32 = _build_canvas_factory( | ||
'CanvasBGRA32', | ||
'numpy.uint8', | ||
'(H, W, 4)', | ||
'MxNx4 (4 channels: blue, green, red, and alpha)', | ||
) | ||
CanvasRGBA128 = _build_canvas_factory( | ||
'CanvasRGBA128', | ||
'numpy.float32', | ||
'(H, W, 4)', | ||
'MxNx4 (2 channels: red, green, blue, and alpha)', | ||
) | ||
from ._celiagg import (CanvasG8, CanvasGA16, CanvasRGB24, CanvasRGBA32, | ||
CanvasBGRA32, CanvasRGBA128) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# The MIT License (MIT) | ||
# | ||
# Copyright (c) 2016-2021 Celiagg Contributors | ||
# | ||
# Permission is hereby granted, free of charge, to any person obtaining a copy | ||
# of this software and associated documentation files (the "Software"), to deal | ||
# in the Software without restriction, including without limitation the rights | ||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
# copies of the Software, and to permit persons to whom the Software is | ||
# furnished to do so, subject to the following conditions: | ||
# | ||
# The above copyright notice and this permission notice shall be included in | ||
# all copies or substantial portions of the Software. | ||
# | ||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
# SOFTWARE. | ||
# | ||
# Authors: John Wiggins | ||
|
||
cimport _font | ||
cimport _transform | ||
|
||
|
||
cdef extern from "font_cache.h": | ||
cdef cppclass FontCache: | ||
FontCache() | ||
|
||
void activate(_font.Font& font, _transform.trans_affine& transform); | ||
double measure_width(char* str) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# The MIT License (MIT) | ||
# | ||
# Copyright (c) 2016-2021 Celiagg Contributors | ||
# | ||
# Permission is hereby granted, free of charge, to any person obtaining a copy | ||
# of this software and associated documentation files (the "Software"), to deal | ||
# in the Software without restriction, including without limitation the rights | ||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
# copies of the Software, and to permit persons to whom the Software is | ||
# furnished to do so, subject to the following conditions: | ||
# | ||
# The above copyright notice and this permission notice shall be included in | ||
# all copies or substantial portions of the Software. | ||
# | ||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
# SOFTWARE. | ||
# | ||
# Authors: John Wiggins | ||
|
||
from libcpp cimport bool | ||
|
||
cdef extern from "text_support.h": | ||
cdef bool _has_text_rendering() |
Oops, something went wrong.