New version from Timothy Hochberg
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@24221 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -1,61 +1,108 @@
|
|||||||
"""wxFancyText -- methods for rendering XML specified text
|
"""<font weight="bold" size="16">FancyText</font> -- <font style="italic" size="16">methods for rendering XML specified text</font>
|
||||||
|
<font family="swiss" size="12">
|
||||||
|
This module exports four main methods::
|
||||||
|
<font family="fixed" style="slant">
|
||||||
|
def GetExtent(str, dc=None, enclose=True)
|
||||||
|
def GetFullExtent(str, dc=None, enclose=True)
|
||||||
|
def RenderToBitmap(str, background=None, enclose=True)
|
||||||
|
def RenderToDC(str, dc, x, y, enclose=True)
|
||||||
|
</font>
|
||||||
|
In all cases, 'str' is an XML string. Note that start and end tags
|
||||||
|
are only required if *enclose* is set to False. In this case the
|
||||||
|
text should be wrapped in FancyText tags.
|
||||||
|
|
||||||
This module has four main methods:
|
In addition, the module exports one class::
|
||||||
|
<font family="fixed" style="slant">
|
||||||
|
class StaticFancyText(self, window, id, text, background, ...)
|
||||||
|
</font>
|
||||||
|
This class works similar to StaticText except it interprets its text
|
||||||
|
as FancyText.
|
||||||
|
|
||||||
def getExtent(str, dc=None, enclose=1):
|
The text can support<sup>superscripts</sup> and <sub>subscripts</sub>, text
|
||||||
def renderToBitmap(str, background=None, enclose=1)
|
in different <font size="20">sizes</font>, <font color="blue">colors</font>, <font style="italic">styles</font>, <font weight="bold">weights</font> and
|
||||||
def renderToDC(str, dc, x, y, enclose=1)
|
<font family="script">families</font>. It also supports a limited set of symbols,
|
||||||
|
currently <times/>, <infinity/>, <angle/> as well as greek letters in both
|
||||||
|
upper case (<Alpha/><Beta/>...<Omega/>) and lower case (<alpha/><beta/>...<omega/>).
|
||||||
|
|
||||||
In all cases, 'str' is an XML string. The tags in the string can
|
We can use doctest/guitest to display this string in all its marked up glory.
|
||||||
currently specify the font, subscripts, superscripts, and the angle
|
<font family="fixed">
|
||||||
sign. The allowable properties of font are size, family, style, weght,
|
>>> frame = wx.Frame(wx.NULL, -1, "FancyText demo", wx.DefaultPosition)
|
||||||
encoding, and color. See the example on the bottom for a better idea
|
>>> sft = StaticFancyText(frame, -1, __doc__, wx.Brush("light grey", wx.SOLID))
|
||||||
of how this works.
|
>>> frame.SetClientSize(sft.GetSize())
|
||||||
|
>>> didit = frame.Show()
|
||||||
|
>>> from guitest import PauseTests; PauseTests()
|
||||||
|
|
||||||
Note that start and end tags for the string are provided if enclose is
|
</font></font>
|
||||||
True, so for instance, renderToBitmap("X<sub>1</sub>") will work.
|
The End"""
|
||||||
|
# Copyright 2001-2003 Timothy Hochberg
|
||||||
|
# Use as you see fit. No warantees, I cannot be help responsible, etc.
|
||||||
|
import copy
|
||||||
|
import math
|
||||||
|
import sys
|
||||||
|
import wx
|
||||||
|
import xml.parsers.expat
|
||||||
|
|
||||||
"""
|
__all__ = "GetExtent", "GetFullExtent", "RenderToBitmap", "RenderToDC", "StaticFancyText"
|
||||||
# Copyright 2001 Timothy Hochberg
|
|
||||||
# Use as you see fit. No warantees, I cannot be held responsible, etc.
|
|
||||||
|
|
||||||
|
if sys.platform == "win32":
|
||||||
|
_greekEncoding = str(wx.FONTENCODING_CP1253)
|
||||||
|
else:
|
||||||
|
_greekEncoding = str(wx.FONTENCODING_ISO8859_7)
|
||||||
|
|
||||||
|
_families = {"fixed" : wx.FIXED, "default" : wx.DEFAULT, "decorative" : wx.DECORATIVE, "roman" : wx.ROMAN,
|
||||||
# TODO: Make a wxFancyTextCtrl class that derives from wxControl.
|
"script" : wx.SCRIPT, "swiss" : wx.SWISS, "modern" : wx.MODERN}
|
||||||
# Add support for line breaks
|
_styles = {"normal" : wx.NORMAL, "slant" : wx.SLANT, "italic" : wx.ITALIC}
|
||||||
# etc.
|
_weights = {"normal" : wx.NORMAL, "light" : wx.LIGHT, "bold" : wx.BOLD}
|
||||||
# - Robin
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
from wxPython.wx import *
|
|
||||||
import xml.parsers.expat, copy
|
|
||||||
|
|
||||||
_families = {"default" : wxDEFAULT, "decorative" : wxDECORATIVE, "roman" : wxROMAN,
|
|
||||||
"swiss" : wxSWISS, "modern" : wxMODERN}
|
|
||||||
_styles = {"normal" : wxNORMAL, "slant" : wxSLANT, "italic" : wxITALIC}
|
|
||||||
_weights = {"normal" : wxNORMAL, "light" : wxLIGHT, "bold" : wxBOLD}
|
|
||||||
|
|
||||||
# The next three classes: Renderer, SizeRenderer and DCRenderer are
|
# The next three classes: Renderer, SizeRenderer and DCRenderer are
|
||||||
# what you will need to override to extend the XML language. All of
|
# what you will need to override to extend the XML language. All of
|
||||||
# the font stuff as well as the subscript and superscript stuff are in
|
# the font stuff as well as the subscript and superscript stuff are in
|
||||||
# Renderer.
|
# Renderer.
|
||||||
|
|
||||||
class Renderer:
|
_greek_letters = ("alpha", "beta", "gamma", "delta", "epsilon", "zeta",
|
||||||
|
"eta", "theta", "iota", "kappa", "lambda", "mu", "nu",
|
||||||
|
"xi", "omnikron", "pi", "rho", "altsigma", "sigma", "tau", "upsilon",
|
||||||
|
"phi", "chi", "psi", "omega")
|
||||||
|
|
||||||
defaultSize = wxNORMAL_FONT.GetPointSize()
|
def iround(number):
|
||||||
defaultFamily = wxDEFAULT
|
return int(round(number))
|
||||||
defaultStyle = wxNORMAL
|
|
||||||
defaultWeight = wxNORMAL
|
def iceil(number):
|
||||||
defaultEncoding = wxFont_GetDefaultEncoding()
|
return int(math.ceil(number))
|
||||||
|
|
||||||
|
class Renderer:
|
||||||
|
"""Class for rendering XML marked up text.
|
||||||
|
|
||||||
|
See the module docstring for a description of the markup.
|
||||||
|
|
||||||
|
This class must be subclassed and the methods the methods that do
|
||||||
|
the drawing overridden for a particular output device.
|
||||||
|
|
||||||
|
"""
|
||||||
|
defaultSize = wx.NORMAL_FONT.GetPointSize()
|
||||||
|
defaultFamily = wx.DEFAULT
|
||||||
|
defaultStyle = wx.NORMAL
|
||||||
|
defaultWeight = wx.NORMAL
|
||||||
|
defaultEncoding = wx.Font_GetDefaultEncoding()
|
||||||
defaultColor = "black"
|
defaultColor = "black"
|
||||||
|
|
||||||
def __init__(self, dc=None):
|
def __init__(self, dc=None, x=0, y=None):
|
||||||
if dc == None:
|
if dc == None:
|
||||||
dc = wxMemoryDC()
|
dc = wx.MemoryDC()
|
||||||
self.dc = dc
|
self.dc = dc
|
||||||
self.offsets = [0]
|
self.offsets = [0]
|
||||||
self.fonts = [{}]
|
self.fonts = [{}]
|
||||||
|
self.width = self.height = 0
|
||||||
|
self.x = x
|
||||||
|
self.minY = self.maxY = self._y = y
|
||||||
|
|
||||||
|
def getY(self):
|
||||||
|
if self._y is None:
|
||||||
|
self.minY = self.maxY = self._y = self.dc.GetTextExtent("M")[1]
|
||||||
|
return self._y
|
||||||
|
def setY(self, value):
|
||||||
|
self._y = y
|
||||||
|
y = property(getY, setY)
|
||||||
|
|
||||||
def startElement(self, name, attrs):
|
def startElement(self, name, attrs):
|
||||||
method = "start_" + name
|
method = "start_" + name
|
||||||
@@ -64,16 +111,37 @@ class Renderer:
|
|||||||
getattr(self, method)(attrs)
|
getattr(self, method)(attrs)
|
||||||
|
|
||||||
def endElement(self, name):
|
def endElement(self, name):
|
||||||
method = "end_" + name
|
methname = "end_" + name
|
||||||
if not hasattr(self, method):
|
if hasattr(self, methname):
|
||||||
raise ValueError("XML tag '%s' not supported" % name)
|
getattr(self, methname)()
|
||||||
getattr(self, method)()
|
elif hasattr(self, "start_" + name):
|
||||||
|
|
||||||
def start_wxFancyString(self, attrs):
|
|
||||||
pass
|
pass
|
||||||
|
else:
|
||||||
|
raise ValueError("XML tag '%s' not supported" % methname)
|
||||||
|
|
||||||
def end_wxFancyString(self):
|
def characterData(self, data):
|
||||||
|
self.dc.SetFont(self.getCurrentFont())
|
||||||
|
for i, chunk in enumerate(data.split('\n')):
|
||||||
|
if i:
|
||||||
|
self.x = 0
|
||||||
|
self.y = self.mayY = self.maxY + self.dc.GetTextExtent("M")[1]
|
||||||
|
if chunk:
|
||||||
|
width, height, descent, extl = self.dc.GetFullTextExtent(chunk)
|
||||||
|
self.renderCharacterData(data, iround(self.x), iround(self.y + self.offsets[-1] - height + descent))
|
||||||
|
else:
|
||||||
|
width = height = descent = extl = 0
|
||||||
|
self.updateDims(width, height, descent, extl)
|
||||||
|
|
||||||
|
def updateDims(self, width, height, descent, externalLeading):
|
||||||
|
self.x += width
|
||||||
|
self.width = max(self.x, self.width)
|
||||||
|
self.minY = min(self.minY, self.y+self.offsets[-1]-height+descent)
|
||||||
|
self.maxY = max(self.maxY, self.y+self.offsets[-1]+descent)
|
||||||
|
self.height = self.maxY - self.minY
|
||||||
|
|
||||||
|
def start_FancyText(self, attrs):
|
||||||
pass
|
pass
|
||||||
|
start_wxFancyText = start_FancyText # For backward compatibility
|
||||||
|
|
||||||
def start_font(self, attrs):
|
def start_font(self, attrs):
|
||||||
for key, value in attrs.items():
|
for key, value in attrs.items():
|
||||||
@@ -86,7 +154,7 @@ class Renderer:
|
|||||||
elif key == "weight":
|
elif key == "weight":
|
||||||
value = _weights[value]
|
value = _weights[value]
|
||||||
elif key == "encoding":
|
elif key == "encoding":
|
||||||
pass
|
value = int(value)
|
||||||
elif key == "color":
|
elif key == "color":
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
@@ -123,7 +191,7 @@ class Renderer:
|
|||||||
|
|
||||||
def getCurrentFont(self):
|
def getCurrentFont(self):
|
||||||
font = self.fonts[-1]
|
font = self.fonts[-1]
|
||||||
return wxFont(font.get("size", self.defaultSize),
|
return wx.TheFontList.FindOrCreateFont(font.get("size", self.defaultSize),
|
||||||
font.get("family", self.defaultFamily),
|
font.get("family", self.defaultFamily),
|
||||||
font.get("style", self.defaultStyle),
|
font.get("style", self.defaultStyle),
|
||||||
font.get("weight", self.defaultWeight),
|
font.get("weight", self.defaultWeight),
|
||||||
@@ -131,119 +199,212 @@ class Renderer:
|
|||||||
|
|
||||||
def getCurrentColor(self):
|
def getCurrentColor(self):
|
||||||
font = self.fonts[-1]
|
font = self.fonts[-1]
|
||||||
return wxNamedColour(font.get("color", self.defaultColor))
|
return wx.TheColourDatabase.FindColour(font.get("color", self.defaultColor))
|
||||||
|
|
||||||
|
def getCurrentPen(self):
|
||||||
|
return wx.ThePenList.FindOrCreatePen(self.getCurrentColor(), 1, wx.SOLID)
|
||||||
|
|
||||||
|
def renderCharacterData(self, data, x, y):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
||||||
|
def _addGreek():
|
||||||
|
alpha = 0xE1
|
||||||
|
Alpha = 0xC1
|
||||||
|
def end(self):
|
||||||
|
pass
|
||||||
|
for i, name in enumerate(_greek_letters):
|
||||||
|
def start(self, attrs, code=chr(alpha+i)):
|
||||||
|
self.start_font({"encoding" : _greekEncoding})
|
||||||
|
self.characterData(code)
|
||||||
|
self.end_font()
|
||||||
|
setattr(Renderer, "start_%s" % name, start)
|
||||||
|
setattr(Renderer, "end_%s" % name, end)
|
||||||
|
if name == "altsigma":
|
||||||
|
continue # There is no capital for altsigma
|
||||||
|
def start(self, attrs, code=chr(Alpha+i)):
|
||||||
|
self.start_font({"encoding" : _greekEncoding})
|
||||||
|
self.characterData(code)
|
||||||
|
self.end_font()
|
||||||
|
setattr(Renderer, "start_%s" % name.capitalize(), start)
|
||||||
|
setattr(Renderer, "end_%s" % name.capitalize(), end)
|
||||||
|
_addGreek()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SizeRenderer(Renderer):
|
class SizeRenderer(Renderer):
|
||||||
|
"""Processes text as if rendering it, but just computes the size."""
|
||||||
|
|
||||||
def __init__(self, dc=None):
|
def __init__(self, dc=None):
|
||||||
Renderer.__init__(self, dc)
|
Renderer.__init__(self, dc, 0, 0)
|
||||||
self.width = self.height = 0
|
|
||||||
self.minY = self.maxY = 0
|
|
||||||
|
|
||||||
def characterData(self, data):
|
def renderCharacterData(self, data, x, y):
|
||||||
self.dc.SetFont(self.getCurrentFont())
|
pass
|
||||||
width, height = self.dc.GetTextExtent(data)
|
|
||||||
self.width = self.width + width
|
|
||||||
self.minY = min(self.minY, self.offsets[-1])
|
|
||||||
self.maxY = max(self.maxY, self.offsets[-1] + height)
|
|
||||||
self.height = self.maxY - self.minY
|
|
||||||
|
|
||||||
def start_angle(self, attrs):
|
def start_angle(self, attrs):
|
||||||
self.characterData("M")
|
self.characterData("M")
|
||||||
|
|
||||||
def end_angle(self):
|
def start_infinity(self, attrs):
|
||||||
pass
|
width, height = self.dc.GetTextExtent("M")
|
||||||
|
width = max(width, 10)
|
||||||
|
height = max(height, width / 2)
|
||||||
|
self.updateDims(width, height, 0, 0)
|
||||||
|
|
||||||
|
def start_times(self, attrs):
|
||||||
|
self.characterData("M")
|
||||||
|
|
||||||
|
def start_in(self, attrs):
|
||||||
|
self.characterData("M")
|
||||||
|
|
||||||
|
def start_times(self, attrs):
|
||||||
|
self.characterData("M")
|
||||||
|
|
||||||
|
|
||||||
class DCRenderer(Renderer):
|
class DCRenderer(Renderer):
|
||||||
|
"""Renders text to a wxPython device context DC."""
|
||||||
|
|
||||||
def __init__(self, dc=None, x=0, y=0):
|
def renderCharacterData(self, data, x, y):
|
||||||
Renderer.__init__(self, dc)
|
|
||||||
self.x = x
|
|
||||||
self.y = y
|
|
||||||
|
|
||||||
def characterData(self, data):
|
|
||||||
self.dc.SetFont(self.getCurrentFont())
|
|
||||||
self.dc.SetTextForeground(self.getCurrentColor())
|
self.dc.SetTextForeground(self.getCurrentColor())
|
||||||
width, height = self.dc.GetTextExtent(data)
|
self.dc.DrawText(data, x, y)
|
||||||
self.dc.DrawText(data, self.x, self.y + self.offsets[-1])
|
|
||||||
self.x = self.x + width
|
|
||||||
|
|
||||||
def start_angle(self, attrs):
|
def start_angle(self, attrs):
|
||||||
self.dc.SetFont(self.getCurrentFont())
|
self.dc.SetFont(self.getCurrentFont())
|
||||||
self.dc.SetPen(wxPen(self.getCurrentColor(), 1))
|
self.dc.SetPen(self.getCurrentPen())
|
||||||
width, height, descent, leading = self.dc.GetFullTextExtent("M")
|
width, height, descent, leading = self.dc.GetFullTextExtent("M")
|
||||||
y = self.y + self.offsets[-1] + height - descent
|
y = self.y + self.offsets[-1]
|
||||||
self.dc.DrawLine(self.x, y, self.x+width, y)
|
self.dc.DrawLine(iround(self.x), iround(y),iround( self.x+width), iround(y))
|
||||||
self.dc.DrawLine(self.x, y, self.x+width, y-width)
|
self.dc.DrawLine(iround(self.x), iround(y), iround(self.x+width), iround(y-width))
|
||||||
self.x = self.x + width
|
self.updateDims(width, height, descent, leading)
|
||||||
|
|
||||||
def end_angle(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
# This is a rendering function that is primarily used internally,
|
def start_infinity(self, attrs):
|
||||||
# although it could be used externally if one had overridden the
|
self.dc.SetFont(self.getCurrentFont())
|
||||||
# Renderer classes.
|
self.dc.SetPen(self.getCurrentPen())
|
||||||
|
width, height, descent, leading = self.dc.GetFullTextExtent("M")
|
||||||
|
width = max(width, 10)
|
||||||
|
height = max(height, width / 2)
|
||||||
|
self.dc.SetPen(wx.Pen(self.getCurrentColor(), max(1, width/10)))
|
||||||
|
self.dc.SetBrush(wx.TRANSPARENT_BRUSH)
|
||||||
|
y = self.y + self.offsets[-1]
|
||||||
|
r = iround( 0.95 * width / 4)
|
||||||
|
xc = (2*self.x + width) / 2
|
||||||
|
yc = iround(y-1.5*r)
|
||||||
|
self.dc.DrawCircle(xc - r, yc, r)
|
||||||
|
self.dc.DrawCircle(xc + r, yc, r)
|
||||||
|
self.updateDims(width, height, 0, 0)
|
||||||
|
|
||||||
def renderToRenderer(str, renderer, enclose=1):
|
def start_times(self, attrs):
|
||||||
|
self.dc.SetFont(self.getCurrentFont())
|
||||||
|
self.dc.SetPen(self.getCurrentPen())
|
||||||
|
width, height, descent, leading = self.dc.GetFullTextExtent("M")
|
||||||
|
y = self.y + self.offsets[-1]
|
||||||
|
width *= 0.8
|
||||||
|
width = iround(width+.5)
|
||||||
|
self.dc.SetPen(wx.Pen(self.getCurrentColor(), 1))
|
||||||
|
self.dc.DrawLine(iround(self.x), iround(y-width), iround(self.x+width-1), iround(y-1))
|
||||||
|
self.dc.DrawLine(iround(self.x), iround(y-2), iround(self.x+width-1), iround(y-width-1))
|
||||||
|
self.updateDims(width, height, 0, 0)
|
||||||
|
|
||||||
|
|
||||||
|
def RenderToRenderer(str, renderer, enclose=True):
|
||||||
|
try:
|
||||||
if enclose:
|
if enclose:
|
||||||
str = '<?xml version="1.0"?><wxFancyString>%s</wxFancyString>' % str
|
str = '<?xml version="1.0"?><FancyText>%s</FancyText>' % str
|
||||||
p = xml.parsers.expat.ParserCreate()
|
p = xml.parsers.expat.ParserCreate()
|
||||||
p.returns_unicode = 0
|
p.returns_unicode = 0
|
||||||
p.StartElementHandler = renderer.startElement
|
p.StartElementHandler = renderer.startElement
|
||||||
p.EndElementHandler = renderer.endElement
|
p.EndElementHandler = renderer.endElement
|
||||||
p.CharacterDataHandler = renderer.characterData
|
p.CharacterDataHandler = renderer.characterData
|
||||||
p.Parse(str, 1)
|
p.Parse(str, 1)
|
||||||
|
except xml.parsers.expat.error, err:
|
||||||
|
raise ValueError('error parsing text text "%s": %s' % (str, err))
|
||||||
|
|
||||||
|
|
||||||
def getExtent(str, dc=None, enclose=1):
|
# Public interface
|
||||||
|
|
||||||
|
|
||||||
|
def GetExtent(str, dc=None, enclose=True):
|
||||||
"Return the extent of str"
|
"Return the extent of str"
|
||||||
renderer = SizeRenderer(dc)
|
renderer = SizeRenderer(dc)
|
||||||
renderToRenderer(str, renderer, enclose)
|
RenderToRenderer(str, renderer, enclose)
|
||||||
return wxSize(renderer.width, renderer.height)
|
return iceil(renderer.width), iceil(renderer.height) # XXX round up
|
||||||
|
|
||||||
# This should probably only be used internally....
|
|
||||||
|
|
||||||
def getFullExtent(str, dc=None, enclose=1):
|
def GetFullExtent(str, dc=None, enclose=True):
|
||||||
renderer = SizeRenderer(dc)
|
renderer = SizeRenderer(dc)
|
||||||
renderToRenderer(str, renderer, enclose)
|
RenderToRenderer(str, renderer, enclose)
|
||||||
return renderer.width, renderer.height, -renderer.minY
|
return iceil(renderer.width), iceil(renderer.height), -iceil(renderer.minY) # XXX round up
|
||||||
|
|
||||||
def renderToBitmap(str, background=None, enclose=1):
|
|
||||||
|
def RenderToBitmap(str, background=None, enclose=1):
|
||||||
"Return str rendered on a minumum size bitmap"
|
"Return str rendered on a minumum size bitmap"
|
||||||
dc = wxMemoryDC()
|
dc = wx.MemoryDC()
|
||||||
width, height, dy = getFullExtent(str, dc)
|
width, height, dy = GetFullExtent(str, dc, enclose)
|
||||||
bmp = wxEmptyBitmap(width, height)
|
bmp = wx.EmptyBitmap(width, height)
|
||||||
dc.SelectObject(bmp)
|
dc.SelectObject(bmp)
|
||||||
if background is not None:
|
if background is None:
|
||||||
|
dc.SetBackground(wx.WHITE_BRUSH)
|
||||||
|
else:
|
||||||
dc.SetBackground(background)
|
dc.SetBackground(background)
|
||||||
dc.Clear()
|
dc.Clear()
|
||||||
renderer = DCRenderer(dc, y=dy)
|
renderer = DCRenderer(dc, y=dy)
|
||||||
dc.BeginDrawing()
|
dc.BeginDrawing()
|
||||||
renderToRenderer(str, renderer, enclose)
|
RenderToRenderer(str, renderer, enclose)
|
||||||
dc.EndDrawing()
|
dc.EndDrawing()
|
||||||
dc.SelectObject(wxNullBitmap)
|
dc.SelectObject(wx.NullBitmap)
|
||||||
|
if background is None:
|
||||||
|
img = wx.ImageFromBitmap(bmp)
|
||||||
|
bg = dc.GetBackground().GetColour()
|
||||||
|
img.SetMaskColour(bg.Red(), bg.Green(), bg.Blue())
|
||||||
|
bmp = img.ConvertToBitmap()
|
||||||
return bmp
|
return bmp
|
||||||
|
|
||||||
def renderToDC(str, dc, x, y, enclose=1):
|
|
||||||
"Render str onto a wxDC at (x,y)"
|
|
||||||
width, height, dy = getFullExtent(str, dc)
|
|
||||||
renderer = DCRenderer(dc, x, y+dy)
|
|
||||||
renderToRenderer(str, renderer, enclose)
|
|
||||||
|
|
||||||
|
def RenderToDC(str, dc, x, y, enclose=1):
|
||||||
|
"Render str onto a wxDC at (x,y)"
|
||||||
|
width, height, dy = GetFullExtent(str, dc)
|
||||||
|
renderer = DCRenderer(dc, x, y+dy)
|
||||||
|
RenderToRenderer(str, renderer, enclose)
|
||||||
|
|
||||||
|
|
||||||
|
class StaticFancyText(wx.StaticBitmap):
|
||||||
|
def __init__(self, window, id, text, *args, **kargs):
|
||||||
|
args = list(args)
|
||||||
|
kargs.setdefault('name', 'staticFancyText')
|
||||||
|
if 'background' in kargs:
|
||||||
|
background = kargs.pop('background')
|
||||||
|
elif args:
|
||||||
|
background = args.pop(0)
|
||||||
|
else:
|
||||||
|
background = wx.Brush(window.GetBackgroundColour(), wx.SOLID)
|
||||||
|
|
||||||
|
bmp = RenderToBitmap(text, background)
|
||||||
|
wx.StaticBitmap.__init__(self, window, id, bmp, *args, **kargs)
|
||||||
|
|
||||||
|
|
||||||
|
# Old names for backward compatibiliry
|
||||||
|
getExtent = GetExtent
|
||||||
|
renderToBitmap = RenderToBitmap
|
||||||
|
renderToDC = RenderToDC
|
||||||
|
|
||||||
|
|
||||||
|
# Test Driver
|
||||||
|
|
||||||
|
def test():
|
||||||
|
app = wx.PyApp()
|
||||||
|
box = wx.BoxSizer(wx.VERTICAL)
|
||||||
|
frame = wx.Frame(wx.NULL, -1, "FancyText demo", wx.DefaultPosition)
|
||||||
|
frame.SetBackgroundColour("light grey")
|
||||||
|
sft = StaticFancyText(frame, -1, __doc__)
|
||||||
|
box.Add(sft, 1, wx.EXPAND)
|
||||||
|
frame.SetSizer(box)
|
||||||
|
frame.SetAutoLayout(True)
|
||||||
|
box.Fit(frame)
|
||||||
|
box.SetSizeHints(frame)
|
||||||
|
frame.Show()
|
||||||
|
app.MainLoop()
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
str = ('<font style="italic" family="swiss" color="red" weight="bold" >some |<sup>23</sup> <angle/>text<sub>with <angle/> subscript</sub> </font> some other text'
|
test()
|
||||||
'<font family="swiss" color="green" size="40">big green text</font>')
|
|
||||||
ID_EXIT = 102
|
|
||||||
class myApp(wxApp):
|
|
||||||
def OnInit(self):
|
|
||||||
return 1
|
|
||||||
app = myApp()
|
|
||||||
frame = wxFrame(NULL, -1, "wxFancyText demo", wxDefaultPosition)
|
|
||||||
frame.SetClientSize(getExtent(str))
|
|
||||||
bmp = renderToBitmap(str, wxCYAN_BRUSH)
|
|
||||||
sb = wxStaticBitmap(frame, -1, bmp)
|
|
||||||
EVT_MENU(frame, ID_EXIT, frame.Destroy)
|
|
||||||
frame.Show(1)
|
|
||||||
app.MainLoop()
|
|
||||||
|
Reference in New Issue
Block a user