Files
blender-portable-repo/scripts/addons/RetopoFlow/addon_common/common/fontmanager.py
T
2026-03-17 14:30:01 -06:00

192 lines
6.1 KiB
Python

'''
Copyright (C) 2023 CG Cookie
http://cgcookie.com
hello@cgcookie.com
Created by Jonathan Denning, Jonathan Williamson
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
'''
import bpy
import blf
import gpu
from . import gpustate
from .blender import get_path_from_addon_root, get_path_shortened_from_addon_root
from .blender_preferences import get_preferences
from .debug import dprint
from .decorators import blender_version_wrapper, only_in_blender_version
from .profiler import profiler
# https://docs.blender.org/api/current/blf.html
class FontManager:
_cache = {0:0}
_last_fontid = 0
_prefs = get_preferences()
@staticmethod
@property
def last_fontid(): return FontManager._last_fontid
@staticmethod
def get_dpi():
ui_scale = FontManager._prefs.view.ui_scale
pixel_size = FontManager._prefs.system.pixel_size
dpi = 72 # FontManager._prefs.system.dpi
return int(dpi * ui_scale * pixel_size)
@staticmethod
def load(val, load_callback=None):
if val is None:
fontid = FontManager._last_fontid
else:
if val not in FontManager._cache:
# note: loading the same file multiple times is not a problem.
# blender is smart enough to cache
fontid = blf.load(val)
print(f'Addon Common: Loaded font id={fontid}: {val}')
FontManager._cache[val] = fontid
FontManager._cache[fontid] = fontid
if load_callback: load_callback(fontid)
fontid = FontManager._cache[val]
FontManager._last_fontid = fontid
return fontid
@staticmethod
def unload_fontids():
unloaded = []
for name,fontid in FontManager._cache.items():
if type(name) is str:
blf.unload(name)
unloaded += [name]
for name in unloaded:
del FontManager._cache[name]
FontManager._last_fontid = 0
@staticmethod
def unload(filename):
assert filename in FontManager._cache
fontid = FontManager._cache[filename]
# dprint('Unloading font "%s" as id %d' % (filename, fontid))
pass
blf.unload(filename)
del FontManager._cache[filename]
if fontid == FontManager._last_fontid:
FontManager._last_fontid = 0
@staticmethod
def aspect(aspect, fontid=None):
return blf.aspect(FontManager.load(fontid), aspect)
@staticmethod
def blur(radius, fontid=None):
return blf.blur(FontManager.load(fontid), radius)
@staticmethod
def clipping(xymin, xymax, fontid=None):
return blf.clipping(FontManager.load(fontid), *xymin, *xymax)
@staticmethod
def color(color, fontid=None):
blf.color(FontManager.load(fontid), *color)
@staticmethod
def dimensions(text, fontid=None):
return blf.dimensions(FontManager.load(fontid), text)
@staticmethod
def disable(option, fontid=None):
return blf.disable(FontManager.load(fontid), option)
@staticmethod
def disable_rotation(fontid=None):
return blf.disable(FontManager.load(fontid), blf.ROTATION)
@staticmethod
def disable_clipping(fontid=None):
return blf.disable(FontManager.load(fontid), blf.CLIPPING)
@staticmethod
def disable_shadow(fontid=None):
return blf.disable(FontManager.load(fontid), blf.SHADOW)
@staticmethod
def disable_word_wrap(fontid=None):
return blf.disable(FontManager.load(fontid), blf.WORD_WRAP)
@staticmethod
def draw(text, xyz=None, fontsize=None, fontid=None):
fontid = FontManager.load(fontid)
if xyz: blf.position(fontid, *xyz)
if fontsize: FontManager.size(fontsize, fontid=fontid)
return blf.draw(fontid, text)
@staticmethod
def draw_simple(text, xyz):
fontid = FontManager._last_fontid
blf.position(fontid, *xyz)
blend_eqn = gpustate.get_blend() # storing blend settings, because blf.draw used to overwrite them (not sure if still applies)
ret = blf.draw(fontid, text)
gpustate.blend(blend_eqn) # restore blend settings
return ret
@staticmethod
def enable(option, fontid=None):
return blf.enable(FontManager.load(fontid), option)
@staticmethod
def enable_rotation(fontid=None):
return blf.enable(FontManager.load(fontid), blf.ROTATION)
@staticmethod
def enable_clipping(fontid=None):
return blf.enable(FontManager.load(fontid), blf.CLIPPING)
@staticmethod
def enable_shadow(fontid=None):
return blf.enable(FontManager.load(fontid), blf.SHADOW)
@staticmethod
def enable_word_wrap(fontid=None):
# note: not a listed option in docs for `blf.enable`, but see `blf.word_wrap`
return blf.enable(FontManager.load(fontid), blf.WORD_WRAP)
@staticmethod
def position(xyz, fontid=None):
return blf.position(FontManager.load(fontid), *xyz)
@staticmethod
def rotation(angle, fontid=None):
return blf.rotation(FontManager.load(fontid), angle)
@staticmethod
def shadow(level, rgba, fontid=None):
return blf.shadow(FontManager.load(fontid), level, *rgba)
@staticmethod
def shadow_offset(xy, fontid=None):
return blf.shadow_offset(FontManager.load(fontid), *xy)
@staticmethod
def size(size, fontid=None):
return blf.size(FontManager.load(fontid), size)
@staticmethod
def word_wrap(wrap_width, fontid=None):
return blf.word_wrap(FontManager.load(fontid), wrap_width)