mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-06 06:01:46 +00:00
1202 lines
38 KiB
Ruby
1202 lines
38 KiB
Ruby
#===============================================================================
|
|
# Text colours
|
|
#===============================================================================
|
|
def ctag(color)
|
|
ret=(color.red.to_i << 24)
|
|
ret|=((color.green.to_i) << 16)
|
|
ret|=((color.blue.to_i) << 8)
|
|
ret|=((color.alpha.to_i))
|
|
return sprintf("<c=%08X>",ret)
|
|
end
|
|
|
|
def shadowctag(base,shadow)
|
|
return sprintf("<c2=%s%s>",colorToRgb16(base),colorToRgb16(shadow))
|
|
end
|
|
|
|
def shadowc3tag(base,shadow)
|
|
return sprintf("<c3=%s,%s>",colorToRgb32(base),colorToRgb32(shadow))
|
|
end
|
|
|
|
def shadowctagFromColor(color)
|
|
return shadowc3tag(color,getContrastColor(color))
|
|
end
|
|
|
|
def shadowctagFromRgb(param)
|
|
return shadowctagFromColor(rgbToColor(param))
|
|
end
|
|
|
|
def colorToRgb32(color)
|
|
return "" if !color
|
|
if color.alpha.to_i==255
|
|
return sprintf("%02X%02X%02X",color.red.to_i,color.green.to_i,color.blue.to_i)
|
|
else
|
|
return sprintf("%02X%02X%02X%02X",
|
|
color.red.to_i,color.green.to_i,color.blue.to_i,color.alpha.to_i)
|
|
end
|
|
end
|
|
|
|
def colorToRgb16(color)
|
|
ret=(color.red.to_i>>3)
|
|
ret|=((color.green.to_i>>3)<<5)
|
|
ret|=((color.blue.to_i>>3)<<10)
|
|
return sprintf("%04X",ret)
|
|
end
|
|
|
|
def rgbToColor(param)
|
|
return Font.default_color if !param
|
|
baseint=param.to_i(16)
|
|
if param.length==8 # 32-bit hex
|
|
return Color.new(
|
|
(baseint>>24)&0xFF,
|
|
(baseint>>16)&0xFF,
|
|
(baseint>>8)&0xFF,
|
|
(baseint)&0xFF
|
|
)
|
|
elsif param.length==6 # 24-bit hex
|
|
return Color.new(
|
|
(baseint>>16)&0xFF,
|
|
(baseint>>8)&0xFF,
|
|
(baseint)&0xFF
|
|
)
|
|
elsif param.length==4 # 16-bit hex
|
|
return Color.new(
|
|
((baseint)&0x1F)<<3,
|
|
((baseint>>5)&0x1F)<<3,
|
|
((baseint>>10)&0x1F)<<3
|
|
)
|
|
elsif param.length==1 # Color number
|
|
i=param.to_i
|
|
return Font.default_color if i>=8
|
|
return [
|
|
Color.new(255, 255, 255, 255),
|
|
Color.new(128, 128, 255, 255),
|
|
Color.new(255, 128, 128, 255),
|
|
Color.new(128, 255, 128, 255),
|
|
Color.new(128, 255, 255, 255),
|
|
Color.new(255, 128, 255, 255),
|
|
Color.new(255, 255, 128, 255),
|
|
Color.new(192, 192, 192, 255)
|
|
][i]
|
|
else
|
|
return Font.default_color
|
|
end
|
|
end
|
|
|
|
def Rgb16ToColor(param)
|
|
baseint=param.to_i(16)
|
|
return Color.new(
|
|
((baseint)&0x1F)<<3,
|
|
((baseint>>5)&0x1F)<<3,
|
|
((baseint>>10)&0x1F)<<3
|
|
)
|
|
end
|
|
|
|
def getContrastColor(color)
|
|
raise "No color given" if !color
|
|
r=color.red; g=color.green; b=color.blue
|
|
yuv=[
|
|
r * 0.299 + g * 0.587 + b * 0.114,
|
|
r * -0.1687 + g * -0.3313 + b * 0.500 + 0.5,
|
|
r * 0.500 + g * -0.4187 + b * -0.0813 + 0.5
|
|
]
|
|
if yuv[0]<127.5
|
|
yuv[0]+=(255-yuv[0])/2
|
|
else
|
|
yuv[0]=yuv[0]/2
|
|
end
|
|
return Color.new(
|
|
yuv[0] + 1.4075 * (yuv[2] - 0.5),
|
|
yuv[0] - 0.3455 * (yuv[1] - 0.5) - 0.7169 * (yuv[2] - 0.5),
|
|
yuv[0] + 1.7790 * (yuv[1] - 0.5),
|
|
color.alpha
|
|
)
|
|
end
|
|
|
|
|
|
|
|
#===============================================================================
|
|
# Format text
|
|
#===============================================================================
|
|
FORMATREGEXP = /<(\/?)(c|c2|c3|o|fn|br|fs|i|b|r|pg|pog|u|s|icon|img|ac|ar|al|outln|outln2)(\s*\=\s*([^>]*))?>/i
|
|
|
|
def fmtescape(text)
|
|
if text[/[&<>]/]
|
|
text2=text.gsub(/&/,"&")
|
|
text2.gsub!(/</,"<")
|
|
text2.gsub!(/>/,">")
|
|
return text2
|
|
end
|
|
return text
|
|
end
|
|
|
|
def toUnformattedText(text)
|
|
text2=text.gsub(FORMATREGEXP,"")
|
|
text2.gsub!(/</,"<")
|
|
text2.gsub!(/>/,">")
|
|
text2.gsub!(/'/,"'")
|
|
text2.gsub!(/"/,"\"")
|
|
text2.gsub!(/&/,"&")
|
|
return text2
|
|
end
|
|
|
|
def unformattedTextLength(text)
|
|
return toUnformattedText(text).scan(/./m).length
|
|
end
|
|
|
|
def itemIconTag(item)
|
|
return "" if !item
|
|
if item.respond_to?("icon_name")
|
|
return sprintf("<icon=%s>",item.icon_name)
|
|
else
|
|
ix=item.icon_index % 16 * 24
|
|
iy=item.icon_index / 16 * 24
|
|
return sprintf("<img=Graphics/System/Iconset|%d|%d|24|24>",ix,iy)
|
|
end
|
|
end
|
|
|
|
def getFormattedTextForDims(bitmap,xDst,yDst,widthDst,heightDst,text,lineheight,
|
|
newlineBreaks=true,explicitBreaksOnly=false)
|
|
text2=text.gsub(/<(\/?)(c|c2|c3|o|u|s)(\s*\=\s*([^>]*))?>/i,"")
|
|
if newlineBreaks
|
|
text2.gsub!(/<(\/?)(br)(\s*\=\s*([^>]*))?>/i,"\n")
|
|
end
|
|
return getFormattedText(
|
|
bitmap,xDst,yDst,widthDst,heightDst,
|
|
text2,lineheight,newlineBreaks,
|
|
explicitBreaksOnly,true)
|
|
end
|
|
|
|
def getFormattedTextFast(bitmap,xDst,yDst,widthDst,heightDst,text,lineheight,
|
|
newlineBreaks=true,explicitBreaksOnly=false)
|
|
x=y=0
|
|
characters=[]
|
|
textchunks=[]
|
|
textchunks.push(text)
|
|
text=textchunks.join("")
|
|
textchars=text.scan(/./m)
|
|
lastword=[0,0] # position of last word
|
|
hadspace=false
|
|
hadnonspace=false
|
|
bold=bitmap.font.bold
|
|
italic=bitmap.font.italic
|
|
colorclone=bitmap.font.color
|
|
defaultfontname=bitmap.font.name
|
|
if defaultfontname.is_a?(Array)
|
|
defaultfontname=defaultfontname.find { |i| Font.exist?(i) } || "Arial"
|
|
elsif !Font.exist?(defaultfontname)
|
|
defaultfontname="Arial"
|
|
end
|
|
defaultfontname=defaultfontname.clone
|
|
havenl=false
|
|
position=0
|
|
while position<textchars.length
|
|
yStart=0
|
|
xStart=0
|
|
width=isWaitChar(textchars[position]) ? 0 : bitmap.text_size(textchars[position]).width
|
|
if textchars[position]=="\n"
|
|
if newlineBreaks # treat newline as break
|
|
havenl=true
|
|
characters.push(["\n",x,y*lineheight+yDst,0,lineheight,false,false,
|
|
false,colorclone,nil,false,false,"",8,position,nil,0])
|
|
y+=1
|
|
x=0
|
|
hadspace=true
|
|
hadnonspace=false
|
|
position+=1
|
|
next
|
|
else # treat newline as space
|
|
textchars[position]=" "
|
|
end
|
|
end
|
|
isspace=(textchars[position][/\s/]||isWaitChar(textchars[position])) ? true : false
|
|
if hadspace && !isspace
|
|
# set last word to here
|
|
lastword[0]=characters.length
|
|
lastword[1]=x
|
|
hadspace=false
|
|
hadnonspace=true
|
|
elsif isspace
|
|
hadspace=true
|
|
end
|
|
texty=(lineheight*y)+yDst+yStart
|
|
# Push character
|
|
if heightDst<0 || yStart<yDst+heightDst
|
|
havenl=true if isWaitChar(textchars[position])
|
|
characters.push([
|
|
textchars[position],
|
|
x+xStart,texty+yStart,width+2,lineheight,
|
|
false,bold,italic,colorclone,nil,false,false,
|
|
defaultfontname,bitmap.font.size,position,nil,0])
|
|
end
|
|
x+=width
|
|
if !explicitBreaksOnly && x+2>widthDst && lastword[1]!=0 &&
|
|
(!hadnonspace || !hadspace)
|
|
havenl=true
|
|
characters.insert(lastword[0],["\n",x,y*lineheight+yDst,0,lineheight,
|
|
false,false,false,colorclone,nil,false,false,"",8,position])
|
|
lastword[0]+=1
|
|
y+=1
|
|
x=0
|
|
for i in lastword[0]...characters.length
|
|
characters[i][2]+=lineheight
|
|
charwidth=characters[i][3]-2
|
|
characters[i][1]=x
|
|
x+=charwidth
|
|
end
|
|
lastword[1]=0
|
|
end
|
|
position+=1
|
|
end
|
|
# This code looks at whether the text occupies exactly two lines when
|
|
# displayed. If it does, it balances the length of each line.
|
|
=begin
|
|
# Count total number of lines
|
|
numlines = (x==0 && y>0) ? y-1 : y
|
|
realtext = (newlineBreaks) ? text : text.gsub(/\n/," ")
|
|
if numlines==2 && !explicitBreaksOnly && !realtext[/\n/] && realtext.length>=50
|
|
# Set half to middle of text (known to contain no formatting)
|
|
half = realtext.length/2
|
|
leftSearch = 0
|
|
rightSearch = 0
|
|
# Search left for a space
|
|
i = half; while i>=0
|
|
break if realtext[i,1][/\s/]||isWaitChar(realtext[i]) # found a space
|
|
leftSearch += 1
|
|
i -= 1
|
|
end
|
|
# Search right for a space
|
|
i = half; while i<realtext.length
|
|
break if realtext[i,1][/\s/]||isWaitChar(realtext[i]) # found a space
|
|
rightSearch += 1
|
|
i += 1
|
|
end
|
|
# Move half left or right whichever is closer
|
|
trialHalf = half+((leftSearch<rightSearch) ? -leftSearch : rightSearch)
|
|
if trialHalf!=0 && trialHalf!=realtext.length
|
|
# Insert newline and re-call this function (force explicitBreaksOnly)
|
|
newText = realtext.clone
|
|
newText.insert(trialHalf,"\n")
|
|
return getFormattedTextFast(bitmap,xDst,yDst,
|
|
widthDst,heightDst,newText,lineheight,true,explicitBreaksOnly)
|
|
end
|
|
end
|
|
=end
|
|
# Eliminate spaces before newlines and pause character
|
|
if havenl
|
|
firstspace=-1
|
|
for i in 0...characters.length
|
|
if characters[i][5]!=false # If not a character
|
|
firstspace=-1
|
|
elsif (characters[i][0]=="\n" || isWaitChar(characters[i][0])) &&
|
|
firstspace>=0
|
|
for j in firstspace...i
|
|
characters[j]=nil
|
|
end
|
|
firstspace=-1
|
|
elsif characters[i][0][/[ \r\t]/]
|
|
if firstspace<0
|
|
firstspace=i
|
|
end
|
|
else
|
|
firstspace=-1
|
|
end
|
|
end
|
|
if firstspace>0
|
|
for j in firstspace...characters.length
|
|
characters[j]=nil
|
|
end
|
|
end
|
|
characters.compact!
|
|
end
|
|
for i in 0...characters.length
|
|
characters[i][1]=xDst+characters[i][1]
|
|
end
|
|
# Remove all characters with Y greater or equal to _yDst_+_heightDst_
|
|
if heightDst>=0
|
|
for i in 0...characters.length
|
|
if characters[i][2]>=yDst+heightDst
|
|
characters[i]=nil
|
|
end
|
|
end
|
|
characters.compact!
|
|
end
|
|
return characters
|
|
end
|
|
|
|
def isWaitChar(x)
|
|
return (x=="\001" || x=="\002")
|
|
end
|
|
|
|
def getLastParam(array,default)
|
|
i=array.length-1
|
|
while i>=0
|
|
return array[i] if array[i]
|
|
i-=1
|
|
end
|
|
return default
|
|
end
|
|
|
|
def getLastColors(colorstack,opacitystack,defaultcolors)
|
|
colors=getLastParam(colorstack,defaultcolors)
|
|
opacity=getLastParam(opacitystack,255)
|
|
if opacity!=255
|
|
colors=[Color.new(colors[0].red,colors[0].green,colors[0].blue,
|
|
colors[0].alpha*opacity/255),
|
|
colors[1] ? Color.new(colors[1].red,colors[1].green,colors[1].blue,
|
|
colors[1].alpha*opacity/255) : nil]
|
|
end
|
|
return colors
|
|
end
|
|
|
|
|
|
|
|
#===============================================================================
|
|
# Formats a string of text and returns an array containing a list of formatted
|
|
# characters.
|
|
#===============================================================================
|
|
=begin
|
|
Parameters:
|
|
bitmap: Source bitmap. Will be used to determine the default font of
|
|
the text.
|
|
xDst: X coordinate of the text's top left corner.
|
|
yDst: Y coordinate of the text's top left corner.
|
|
widthDst: Width of the text. Used to determine line breaks.
|
|
heightDst: Height of the text. If -1, there is no height restriction. If
|
|
1 or greater, any characters exceeding the height are removed
|
|
from the returned list.
|
|
newLineBreaks: If true, newline characters will be treated as line breaks. The
|
|
default is true.
|
|
|
|
Return Values:
|
|
A list of formatted characters. Returns an empty array if _bitmap_ is nil
|
|
or disposed, or if _widthDst_ is 0 or less or _heightDst_ is 0.
|
|
|
|
Formatting Specification:
|
|
This function uses the following syntax when formatting the text.
|
|
<b> ... </b> - Formats the text in bold.
|
|
<i> ... </i> - Formats the text in italics.
|
|
<u> ... </u> - Underlines the text.
|
|
<s> ... </s> - Draws a strikeout line over the text.
|
|
<al> ... </al> - Left-aligns the text. Causes line breaks before and after
|
|
the text.
|
|
<r> - Right-aligns the text until the next line break.
|
|
<ar> ... </ar> - Right-aligns the text. Causes line breaks before and after
|
|
the text.
|
|
<ac> ... </ac> - Centers the text. Causes line breaks before and after the
|
|
text.
|
|
<br> - Causes a line break.
|
|
<c=X> ... </c> - Color specification. A total of four formats are supported:
|
|
RRGGBBAA, RRGGBB, 16-bit RGB, and Window_Base color numbers.
|
|
<c2=X> ... </c2> - Color specification where the first half is the base color
|
|
and the second half is the shadow color. 16-bit RGB is
|
|
supported.
|
|
Added 2009-10-20
|
|
<c3=B,S> ... </c3> - Color specification where B is the base color and S is the
|
|
shadow color. B and/or S can be omitted. A total of four
|
|
formats are supported:
|
|
RRGGBBAA, RRGGBB, 16-bit RGB, and Window_Base color numbers.
|
|
Added 2009-9-12
|
|
<o=X> - Displays the text in the given opacity (0-255)
|
|
Added 2009-10-19
|
|
<outln> - Displays the text in outline format.
|
|
Added 2010-05-12
|
|
<outln2> - Displays the text in outline format (outlines more
|
|
exaggerated.
|
|
<fn=X> ... </fn> - Formats the text in the specified font, or Arial if the
|
|
font doesn't exist.
|
|
<fs=X> ... </fs> - Changes the font size to X.
|
|
<icon=X> - Displays the icon X (in Graphics/Icons/).
|
|
|
|
In addition, the syntax supports the following:
|
|
' - Converted to "'".
|
|
< - Converted to "<".
|
|
> - Converted to ">".
|
|
& - Converted to "&".
|
|
" - Converted to double quotation mark.
|
|
|
|
To draw the characters, pass the returned array to the
|
|
_drawFormattedChars_ function.
|
|
=end
|
|
|
|
def getFormattedText(bitmap,xDst,yDst,widthDst,heightDst,text,lineheight=32,
|
|
newlineBreaks=true,explicitBreaksOnly=false,
|
|
collapseAlignments=false)
|
|
dummybitmap=nil
|
|
if !bitmap || bitmap.disposed? # allows function to be called with nil bitmap
|
|
dummybitmap=Bitmap.new(1,1)
|
|
bitmap=dummybitmap
|
|
return
|
|
end
|
|
if !bitmap || bitmap.disposed? || widthDst<=0 || heightDst==0 || text.length==0
|
|
return []
|
|
end
|
|
textchunks=[]
|
|
controls=[]
|
|
oldtext=text
|
|
while text[FORMATREGEXP]
|
|
textchunks.push($~.pre_match)
|
|
if $~[3]
|
|
controls.push([$~[2].downcase,$~[4],-1,$~[1]=="/" ? true : false])
|
|
else
|
|
controls.push([$~[2].downcase,"",-1,$~[1]=="/" ? true : false])
|
|
end
|
|
text=$~.post_match
|
|
end
|
|
if controls.length==0
|
|
ret=getFormattedTextFast(bitmap,xDst,yDst,widthDst,heightDst,text,lineheight,
|
|
newlineBreaks,explicitBreaksOnly)
|
|
dummybitmap.dispose if dummybitmap
|
|
return ret
|
|
end
|
|
x=y=0
|
|
characters=[]
|
|
charactersInternal=[]
|
|
realtext=nil
|
|
realtextStart=""
|
|
if !explicitBreaksOnly && textchunks.join("").length==0
|
|
# All commands occurred at the beginning of the text string
|
|
realtext=(newlineBreaks) ? text : text.gsub(/\n/," ")
|
|
realtextStart=oldtext[0,oldtext.length-realtext.length]
|
|
realtextHalf=text.length/2
|
|
end
|
|
textchunks.push(text)
|
|
for chunk in textchunks
|
|
chunk.gsub!(/</,"<")
|
|
chunk.gsub!(/>/,">")
|
|
chunk.gsub!(/'/,"'")
|
|
chunk.gsub!(/"/,"\"")
|
|
chunk.gsub!(/&/,"&")
|
|
end
|
|
textlen=0
|
|
for i in 0...controls.length
|
|
textlen+=textchunks[i].scan(/./m).length
|
|
controls[i][2]=textlen
|
|
end
|
|
text=textchunks.join("")
|
|
textchars=text.scan(/./m)
|
|
colorstack=[]
|
|
boldcount=0
|
|
italiccount=0
|
|
outlinecount=0
|
|
underlinecount=0
|
|
strikecount=0
|
|
rightalign=0
|
|
outline2count=0
|
|
opacitystack=[]
|
|
oldfont=bitmap.font.clone
|
|
defaultfontname=bitmap.font.name
|
|
defaultfontsize=bitmap.font.size
|
|
fontsize=defaultfontsize
|
|
fontnamestack=[]
|
|
fontsizestack=[]
|
|
defaultcolors=[oldfont.color.clone,nil]
|
|
if defaultfontname.is_a?(Array)
|
|
defaultfontname=defaultfontname.find { |i| Font.exist?(i) } || "Arial"
|
|
elsif !Font.exist?(defaultfontname)
|
|
defaultfontname="Arial"
|
|
end
|
|
defaultfontname=defaultfontname.clone
|
|
fontname=defaultfontname
|
|
alignstack=[]
|
|
lastword=[0,0] # position of last word
|
|
hadspace=false
|
|
hadnonspace=false
|
|
havenl=false
|
|
position=0
|
|
while position<textchars.length
|
|
nextline=0
|
|
graphic=nil
|
|
graphicX=0
|
|
graphicY=0
|
|
graphicWidth=nil
|
|
graphicHeight=nil
|
|
graphicRect=nil
|
|
for i in 0...controls.length
|
|
if controls[i] && controls[i][2]==position
|
|
control=controls[i][0]
|
|
param=controls[i][1]
|
|
endtag=controls[i][3]
|
|
if control=="c"
|
|
if endtag
|
|
colorstack.pop
|
|
else
|
|
color=rgbToColor(param)
|
|
colorstack.push([color,nil])
|
|
end
|
|
elsif control=="c2"
|
|
if endtag
|
|
colorstack.pop
|
|
else
|
|
base=Rgb16ToColor(param[0,4])
|
|
shadow=Rgb16ToColor(param[4,4])
|
|
colorstack.push([base,shadow])
|
|
end
|
|
elsif control=="c3"
|
|
if endtag
|
|
colorstack.pop
|
|
else
|
|
param=param.split(",")
|
|
# get pure colors unaffected by opacity
|
|
oldColors=getLastParam(colorstack,defaultcolors)
|
|
base=(param[0] && param[0]!="") ? rgbToColor(param[0]) : oldColors[0]
|
|
shadow=(param[1] && param[1]!="") ? rgbToColor(param[1]) : oldColors[1]
|
|
colorstack.push([base,shadow])
|
|
end
|
|
elsif control=="o"
|
|
if endtag
|
|
opacitystack.pop
|
|
else
|
|
opacitystack.push(param.sub(/\s+$/,"").to_i)
|
|
end
|
|
elsif control=="b"
|
|
boldcount+=(endtag ? -1 : 1)
|
|
elsif control=="i"
|
|
italiccount+=(endtag ? -1 : 1)
|
|
elsif control=="u"
|
|
underlinecount+=(endtag ? -1 : 1)
|
|
elsif control=="s"
|
|
strikecount+=(endtag ? -1 : 1)
|
|
elsif control=="outln"
|
|
outlinecount+=(endtag ? -1 : 1)
|
|
elsif control=="outln2"
|
|
outline2count+=(endtag ? -1 : 1)
|
|
elsif control=="fs" # Font size
|
|
if endtag
|
|
fontsizestack.pop
|
|
else
|
|
fontsizestack.push(param.sub(/\s+$/,"").to_i)
|
|
end
|
|
fontsize=getLastParam(fontsizestack,defaultfontsize)
|
|
bitmap.font.size=fontsize
|
|
elsif control=="fn" # Font name
|
|
if endtag
|
|
fontnamestack.pop
|
|
else
|
|
fontname=param.sub(/\s+$/,"")
|
|
fontnamestack.push(Font.exist?(fontname) ? fontname : "Arial")
|
|
end
|
|
fontname=getLastParam(fontnamestack,defaultfontname)
|
|
bitmap.font.name=fontname
|
|
elsif control=="ar" # Right align
|
|
if !endtag
|
|
alignstack.push(1)
|
|
nextline=1 if x>0 && nextline==0
|
|
else
|
|
alignstack.pop
|
|
nextline=1 if x>0 && nextline==0
|
|
end
|
|
elsif control=="al" # Left align
|
|
if !endtag
|
|
alignstack.push(0)
|
|
nextline=1 if x>0 && nextline==0
|
|
else
|
|
alignstack.pop;
|
|
nextline=1 if x>0 && nextline==0
|
|
end
|
|
elsif control=="ac" # Center align
|
|
if !endtag
|
|
alignstack.push(2)
|
|
nextline=1 if x>0 && nextline==0
|
|
else
|
|
alignstack.pop;
|
|
nextline=1 if x>0 && nextline==0
|
|
end
|
|
elsif control=="icon" # Icon
|
|
if !endtag
|
|
param=param.sub(/\s+$/,"")
|
|
graphic="Graphics/Icons/#{param}"
|
|
controls[i]=nil
|
|
break
|
|
end
|
|
elsif control=="img" # Icon
|
|
if !endtag
|
|
param=param.sub(/\s+$/,"")
|
|
param=param.split("|")
|
|
graphic=param[0]
|
|
if param.length>1
|
|
graphicX=param[1].to_i
|
|
graphicY=param[2].to_i
|
|
graphicWidth=param[3].to_i
|
|
graphicHeight=param[4].to_i
|
|
end
|
|
controls[i]=nil
|
|
break
|
|
end
|
|
elsif control=="br" # Line break
|
|
if !endtag
|
|
nextline+=1
|
|
end
|
|
elsif control=="r" # Right align this line
|
|
if !endtag
|
|
x=0
|
|
rightalign=1; lastword=[characters.length,x]
|
|
end
|
|
end
|
|
controls[i]=nil
|
|
end
|
|
end
|
|
bitmap.font.bold=(boldcount>0)
|
|
bitmap.font.italic=(italiccount>0)
|
|
if graphic
|
|
if !graphicWidth
|
|
tempgraphic=Bitmap.new(graphic)
|
|
graphicWidth=tempgraphic.width
|
|
graphicHeight=tempgraphic.height
|
|
tempgraphic.dispose
|
|
end
|
|
width=graphicWidth # +8 # No padding
|
|
xStart=0 # 4
|
|
yStart=[(lineheight/2)-(graphicHeight/2),0].max
|
|
graphicRect=Rect.new(graphicX,graphicY,graphicWidth,graphicHeight)
|
|
else
|
|
yStart=0
|
|
xStart=0
|
|
width=isWaitChar(textchars[position]) ? 0 : bitmap.text_size(textchars[position]).width
|
|
width+=2 if width>0 && outline2count>0
|
|
end
|
|
if rightalign==1 && nextline==0
|
|
alignment=1
|
|
else
|
|
alignment=getLastParam(alignstack,0)
|
|
end
|
|
nextline.times do
|
|
havenl=true
|
|
characters.push(["\n",x,y*lineheight+yDst,0,lineheight,false,false,false,
|
|
defaultcolors[0],defaultcolors[1],false,false,"",8,position,nil,0])
|
|
charactersInternal.push([alignment,y,0])
|
|
y+=1;
|
|
x=0;
|
|
rightalign=0;
|
|
lastword=[characters.length,x]
|
|
hadspace=false
|
|
hadnonspace=false
|
|
end
|
|
if textchars[position]=="\n"
|
|
if newlineBreaks
|
|
if nextline==0
|
|
havenl=true
|
|
characters.push(["\n",x,y*lineheight+yDst,0,lineheight,false,false,false,
|
|
defaultcolors[0],defaultcolors[1],false,false,"",8,position,nil,0])
|
|
charactersInternal.push([alignment,y,0])
|
|
y+=1
|
|
x=0
|
|
end
|
|
rightalign=0
|
|
hadspace=true
|
|
hadnonspace=false
|
|
position+=1
|
|
next
|
|
else
|
|
textchars[position]=" "
|
|
if !graphic
|
|
width=bitmap.text_size(textchars[position]).width
|
|
width+=2 if width>0 && outline2count>0
|
|
end
|
|
end
|
|
end
|
|
isspace=(textchars[position][/\s/] || isWaitChar(textchars[position])) ? true : false
|
|
if hadspace && !isspace
|
|
# set last word to here
|
|
lastword[0]=characters.length
|
|
lastword[1]=x
|
|
hadspace=false
|
|
hadnonspace=true
|
|
elsif isspace
|
|
hadspace=true
|
|
end
|
|
texty=(lineheight*y)+yDst+yStart
|
|
colors=getLastColors(colorstack,opacitystack,defaultcolors)
|
|
# Push character
|
|
if heightDst<0 || texty<yDst+heightDst
|
|
havenl=true if !graphic && isWaitChar(textchars[position])
|
|
extraspace=(!graphic && italiccount>0) ? 2+(width/2) : 2
|
|
characters.push([
|
|
graphic ? graphic : textchars[position],
|
|
x+xStart,texty,width+extraspace,lineheight,
|
|
graphic ? true : false,
|
|
(boldcount>0),(italiccount>0),colors[0],colors[1],
|
|
(underlinecount>0),(strikecount>0),fontname,fontsize,
|
|
position,graphicRect,
|
|
((outlinecount>0) ? 1 : 0)+((outline2count>0) ? 2 : 0)
|
|
])
|
|
charactersInternal.push([alignment,y,xStart,textchars[position],extraspace])
|
|
end
|
|
x+=width
|
|
if !explicitBreaksOnly && x+2>widthDst && lastword[1]!=0 &&
|
|
(!hadnonspace || !hadspace)
|
|
havenl=true
|
|
characters.insert(lastword[0],["\n",x,y*lineheight+yDst,0,lineheight,false,
|
|
false,false,defaultcolors[0],defaultcolors[1],false,false,"",8,position,
|
|
nil])
|
|
charactersInternal.insert(lastword[0],[alignment,y,0])
|
|
lastword[0]+=1
|
|
y+=1
|
|
x=0
|
|
for i in lastword[0]...characters.length
|
|
characters[i][2]+=lineheight
|
|
charactersInternal[i][1]+=1
|
|
extraspace=(charactersInternal[i][4]) ? charactersInternal[i][4] : 0
|
|
charwidth=characters[i][3]-extraspace
|
|
characters[i][1]=x+charactersInternal[i][2]
|
|
x+=charwidth
|
|
end
|
|
lastword[1]=0
|
|
end
|
|
position+=1 if !graphic
|
|
end
|
|
# This code looks at whether the text occupies exactly two lines when
|
|
# displayed. If it does, it balances the length of each line.
|
|
=begin
|
|
# Count total number of lines
|
|
numlines = (x==0 && y>0) ? y : y+1
|
|
if numlines==2 && realtext && !realtext[/\n/] && realtext.length>=50
|
|
# Set half to middle of text (known to contain no formatting)
|
|
half = realtext.length/2
|
|
leftSearch = 0
|
|
rightSearch = 0
|
|
# Search left for a space
|
|
i = half; while i>=0
|
|
break if realtext[i,1][/\s/]||isWaitChar(realtext[i,1]) # found a space
|
|
leftSearch += 1
|
|
i -= 1
|
|
end
|
|
# Search right for a space
|
|
i = half; while i<realtext.length
|
|
break if realtext[i,1][/\s/]||isWaitChar(realtext[i,1]) # found a space
|
|
rightSearch += 1
|
|
i += 1
|
|
end
|
|
# Move half left or right whichever is closer
|
|
trialHalf = half+((rightSearch<leftSearch) ? rightSearch : -leftSearch)
|
|
if trialHalf!=0 && trialHalf!=realtext.length
|
|
# Insert newline and re-call this function (force newlineBreaksOnly)
|
|
newText = realtext.clone
|
|
if isWaitChar(newText[trialHalf,1])
|
|
# insert after wait character
|
|
newText.insert(trialHalf+1,"\n")
|
|
else
|
|
# remove spaces after newline
|
|
newText.insert(trialHalf,"\n")
|
|
newText.gsub!(/\n\s+/,"\n")
|
|
end
|
|
bitmap.font = oldfont
|
|
dummybitmap.dispose if dummybitmap
|
|
return getFormattedText(dummybitmap ? nil : bitmap,xDst,yDst,
|
|
widthDst,heightDst,realtextStart+newText,
|
|
lineheight,true,explicitBreaksOnly)
|
|
end
|
|
end
|
|
=end
|
|
if havenl
|
|
# Eliminate spaces before newlines and pause character
|
|
firstspace=-1
|
|
for i in 0...characters.length
|
|
if characters[i][5]!=false # If not a character
|
|
firstspace=-1
|
|
elsif (characters[i][0]=="\n" || isWaitChar(characters[i][0])) &&
|
|
firstspace>=0
|
|
for j in firstspace...i
|
|
characters[j]=nil
|
|
charactersInternal[j]=nil
|
|
end
|
|
firstspace=-1
|
|
elsif characters[i][0][/[ \r\t]/]
|
|
if firstspace<0
|
|
firstspace=i
|
|
end
|
|
else
|
|
firstspace=-1
|
|
end
|
|
end
|
|
if firstspace>0
|
|
for j in firstspace...characters.length
|
|
characters[j]=nil
|
|
charactersInternal[j]=nil
|
|
end
|
|
end
|
|
characters.compact!
|
|
charactersInternal.compact!
|
|
end
|
|
# Calculate Xs based on alignment
|
|
# First, find all text runs with the same alignment on the same line
|
|
totalwidth=0
|
|
widthblocks=[]
|
|
lastalign=0
|
|
lasty=0
|
|
runstart=0
|
|
for i in 0...characters.length
|
|
c=characters[i]
|
|
if i>0 && (charactersInternal[i][0]!=lastalign ||
|
|
charactersInternal[i][1]!=lasty)
|
|
# Found end of run
|
|
widthblocks.push([runstart,i,lastalign,totalwidth,lasty])
|
|
runstart=i
|
|
totalwidth=0
|
|
end
|
|
lastalign=charactersInternal[i][0]
|
|
lasty=charactersInternal[i][1]
|
|
extraspace=(charactersInternal[i][4]) ? charactersInternal[i][4] : 0
|
|
totalwidth+=c[3]-extraspace
|
|
end
|
|
widthblocks.push([runstart,characters.length,lastalign,totalwidth,lasty])
|
|
if collapseAlignments
|
|
# Calculate the total width of each line
|
|
totalLineWidths=[]
|
|
for block in widthblocks
|
|
y=block[4]
|
|
if !totalLineWidths[y]
|
|
totalLineWidths[y]=0
|
|
end
|
|
if totalLineWidths[y]!=0
|
|
# padding in case more than one line has different alignments
|
|
totalLineWidths[y]+=16
|
|
end
|
|
totalLineWidths[y]+=block[3]
|
|
end
|
|
# Calculate a new width for the next step
|
|
widthDst=[widthDst,(totalLineWidths.compact.max || 0)].min
|
|
end
|
|
# Now, based on the text runs found, recalculate Xs
|
|
for block in widthblocks
|
|
next if block[0]>=block[1]
|
|
for i in block[0]...block[1]
|
|
case block[2]
|
|
when 1; characters[i][1]=xDst+(widthDst-block[3]-4)+characters[i][1]
|
|
when 2; characters[i][1]=xDst+((widthDst/2)-(block[3]/2))+characters[i][1]
|
|
else; characters[i][1]=xDst+characters[i][1]
|
|
end
|
|
end
|
|
end
|
|
# Remove all characters with Y greater or equal to _yDst_+_heightDst_
|
|
if heightDst>=0
|
|
for i in 0...characters.length
|
|
if characters[i][2]>=yDst+heightDst
|
|
characters[i]=nil
|
|
end
|
|
end
|
|
characters.compact!
|
|
end
|
|
bitmap.font=oldfont
|
|
dummybitmap.dispose if dummybitmap
|
|
return characters
|
|
end
|
|
|
|
|
|
|
|
#===============================================================================
|
|
# Draw text and images on a bitmap
|
|
#===============================================================================
|
|
def getLineBrokenChunks(bitmap,value,width,dims,plain=false)
|
|
x=0
|
|
y=0
|
|
textheight=0
|
|
ret=[]
|
|
if dims
|
|
dims[0]=0
|
|
dims[1]=0
|
|
end
|
|
re=/<c=([^>]+)>/
|
|
reNoMatch=/<c=[^>]+>/
|
|
return ret if !bitmap || bitmap.disposed? || width<=0
|
|
textmsg=value.clone
|
|
color=Font.default_color
|
|
while (c = textmsg.slice!(/\n|[^ \r\t\f\n\-]*\-+|(\S*([ \r\t\f]?))/)) != nil
|
|
break if c==""
|
|
ccheck=c
|
|
if ccheck=="\n"
|
|
x=0
|
|
# y+=(textheight==0) ? bitmap.text_size("X").height : textheight
|
|
y+=(textheight==0) ? bitmap.text_size("X").height+1 : textheight
|
|
textheight=0
|
|
next
|
|
end
|
|
if ccheck[/</] && !plain
|
|
textcols=[]
|
|
ccheck.scan(re) { textcols.push(rgbToColor($1)) }
|
|
words=ccheck.split(reNoMatch) # must have no matches because split can include match
|
|
else
|
|
textcols=[]
|
|
words=[ccheck]
|
|
end
|
|
for i in 0...words.length
|
|
word=words[i]
|
|
if word && word!=""
|
|
textSize=bitmap.text_size(word)
|
|
textwidth=textSize.width
|
|
if x>0 && x+textwidth>width
|
|
minTextSize=bitmap.text_size(word.gsub(/\s*/,""))
|
|
if x>0 && x+minTextSize.width>width
|
|
x=0
|
|
y+=32 # (textheight==0) ? bitmap.text_size("X").height : textheight
|
|
# y+=(textheight==0) ? bitmap.text_size("X").height+1 : textheight
|
|
textheight=0
|
|
end
|
|
end
|
|
textheight=32 # [textheight,textSize.height].max
|
|
# textheight=[textheight,textSize.height+1].max
|
|
ret.push([word,x,y,textwidth,textheight,color])
|
|
x+=textwidth
|
|
dims[0]=x if dims && dims[0]<x
|
|
end
|
|
if textcols[i]
|
|
color=textcols[i]
|
|
end
|
|
end
|
|
end
|
|
dims[1]=y+textheight if dims
|
|
return ret
|
|
end
|
|
|
|
def renderLineBrokenChunks(bitmap,xDst,yDst,normtext,maxheight=0)
|
|
for i in 0...normtext.length
|
|
width=normtext[i][3]
|
|
textx=normtext[i][1]+xDst
|
|
texty=normtext[i][2]+yDst
|
|
if maxheight==0 || normtext[i][2]<maxheight
|
|
bitmap.font.color=normtext[i][5]
|
|
bitmap.draw_text(textx,texty,width+2,normtext[i][4],normtext[i][0])
|
|
end
|
|
end
|
|
end
|
|
|
|
def renderLineBrokenChunksWithShadow(bitmap,xDst,yDst,normtext,maxheight,baseColor,shadowColor)
|
|
for i in 0...normtext.length
|
|
width=normtext[i][3]
|
|
textx=normtext[i][1]+xDst
|
|
texty=normtext[i][2]+yDst
|
|
if maxheight==0 || normtext[i][2]<maxheight
|
|
height=normtext[i][4]
|
|
text=normtext[i][0]
|
|
bitmap.font.color=shadowColor
|
|
bitmap.draw_text(textx+2,texty,width+2,height,text)
|
|
bitmap.draw_text(textx,texty+2,width+2,height,text)
|
|
bitmap.draw_text(textx+2,texty+2,width+2,height,text)
|
|
bitmap.font.color=baseColor
|
|
bitmap.draw_text(textx,texty,width+2,height,text)
|
|
end
|
|
end
|
|
end
|
|
|
|
def drawBitmapBuffer(chars)
|
|
width=1
|
|
height=1
|
|
for ch in chars
|
|
chx=ch[1]+ch[3]
|
|
chy=ch[2]+ch[4]
|
|
width=chx if width<chx
|
|
height=chy if height<chy
|
|
end
|
|
buffer=Bitmap.new(width,height)
|
|
drawFormattedChars(buffer,chars)
|
|
return buffer
|
|
end
|
|
|
|
def drawSingleFormattedChar(bitmap,ch)
|
|
if ch[5] # If a graphic
|
|
graphic=Bitmap.new(ch[0])
|
|
graphicRect=ch[15]
|
|
bitmap.blt(ch[1], ch[2], graphic,graphicRect,ch[8].alpha)
|
|
graphic.dispose
|
|
else
|
|
bitmap.font.size=ch[13] if bitmap.font.size!=ch[13]
|
|
if ch[0]!="\n" && ch[0]!="\r" && ch[0]!=" " && !isWaitChar(ch[0])
|
|
bitmap.font.bold=ch[6] if bitmap.font.bold!=ch[6]
|
|
bitmap.font.italic=ch[7] if bitmap.font.italic!=ch[7]
|
|
bitmap.font.name=ch[12] if bitmap.font.name!=ch[12]
|
|
offset=0
|
|
if ch[9] # shadow
|
|
bitmap.font.color=ch[9]
|
|
if (ch[16]&1)!=0 # outline
|
|
offset=1
|
|
bitmap.draw_text(ch[1],ch[2],ch[3]+2,ch[4],ch[0])
|
|
bitmap.draw_text(ch[1],ch[2]+1,ch[3]+2,ch[4],ch[0])
|
|
bitmap.draw_text(ch[1],ch[2]+2,ch[3]+2,ch[4],ch[0])
|
|
bitmap.draw_text(ch[1]+1,ch[2],ch[3]+2,ch[4],ch[0])
|
|
bitmap.draw_text(ch[1]+1,ch[2]+2,ch[3]+2,ch[4],ch[0])
|
|
bitmap.draw_text(ch[1]+2,ch[2],ch[3]+2,ch[4],ch[0])
|
|
bitmap.draw_text(ch[1]+2,ch[2]+1,ch[3]+2,ch[4],ch[0])
|
|
bitmap.draw_text(ch[1]+2,ch[2]+2,ch[3]+2,ch[4],ch[0])
|
|
elsif (ch[16]&2)!=0 # outline 2
|
|
offset=2
|
|
bitmap.draw_text(ch[1],ch[2],ch[3]+4,ch[4],ch[0])
|
|
bitmap.draw_text(ch[1],ch[2]+2,ch[3]+4,ch[4],ch[0])
|
|
bitmap.draw_text(ch[1],ch[2]+4,ch[3]+4,ch[4],ch[0])
|
|
bitmap.draw_text(ch[1]+2,ch[2],ch[3]+4,ch[4],ch[0])
|
|
bitmap.draw_text(ch[1]+2,ch[2]+4,ch[3]+4,ch[4],ch[0])
|
|
bitmap.draw_text(ch[1]+4,ch[2],ch[3]+4,ch[4],ch[0])
|
|
bitmap.draw_text(ch[1]+4,ch[2]+2,ch[3]+4,ch[4],ch[0])
|
|
bitmap.draw_text(ch[1]+4,ch[2]+4,ch[3]+4,ch[4],ch[0])
|
|
else
|
|
bitmap.draw_text(ch[1]+2,ch[2],ch[3]+2,ch[4],ch[0])
|
|
bitmap.draw_text(ch[1],ch[2]+2,ch[3]+2,ch[4],ch[0])
|
|
bitmap.draw_text(ch[1]+2,ch[2]+2,ch[3]+2,ch[4],ch[0])
|
|
end
|
|
end
|
|
bitmap.font.color=ch[8] if bitmap.font.color!=ch[8]
|
|
bitmap.draw_text(ch[1]+offset,ch[2]+offset,ch[3],ch[4],ch[0])
|
|
else
|
|
bitmap.font.color=ch[8] if bitmap.font.color!=ch[8]
|
|
end
|
|
if ch[10] # underline
|
|
bitmap.fill_rect(ch[1],ch[2]+ch[4]-[(ch[4]-bitmap.font.size)/2,0].max-2,
|
|
ch[3]-2,2,ch[8])
|
|
end
|
|
if ch[11] # strikeout
|
|
bitmap.fill_rect(ch[1],ch[2]+(ch[4]/2),ch[3]-2,2,ch[8])
|
|
end
|
|
end
|
|
end
|
|
|
|
def drawFormattedChars(bitmap,chars)
|
|
return if chars.length==0 || !bitmap||bitmap.disposed?
|
|
oldfont=bitmap.font.clone
|
|
for ch in chars
|
|
drawSingleFormattedChar(bitmap,ch)
|
|
end
|
|
bitmap.font=oldfont
|
|
end
|
|
|
|
def drawTextTable(bitmap,x,y,totalWidth,rowHeight,columnWidthPercents,table)
|
|
yPos=y
|
|
for i in 0...table.length
|
|
row=table[i]
|
|
xPos=x
|
|
for j in 0...row.length
|
|
cell=row[j]
|
|
cellwidth=columnWidthPercents[j]*totalWidth/100
|
|
chars=getFormattedText(bitmap,xPos,yPos,cellwidth,-1,cell,rowHeight)
|
|
drawFormattedChars(bitmap,chars)
|
|
xPos+=cellwidth
|
|
end
|
|
yPos+=rowHeight
|
|
end
|
|
end
|
|
|
|
def drawTextEx(bitmap,x,y,width,numlines,text,baseColor,shadowColor)
|
|
normtext=getLineBrokenChunks(bitmap,text,width,nil,true)
|
|
renderLineBrokenChunksWithShadow(bitmap,x,y,normtext,numlines*32,
|
|
baseColor,shadowColor)
|
|
end
|
|
|
|
def drawFormattedTextEx(bitmap,x,y,width,text,baseColor=nil,shadowColor=nil,lineheight=32)
|
|
base=!baseColor ? Color.new(12*8,12*8,12*8) : baseColor.clone
|
|
shadow=!shadowColor ? Color.new(26*8,26*8,25*8) : shadowColor.clone
|
|
text="<c2="+colorToRgb16(base)+colorToRgb16(shadow)+">"+text
|
|
chars=getFormattedText(bitmap,x,y,width,-1,text,lineheight)
|
|
drawFormattedChars(bitmap,chars)
|
|
end
|
|
|
|
# Deprecated -- not to be used in new code
|
|
def coloredToFormattedText(text,baseColor=nil,shadowColor=nil)
|
|
base=!baseColor ? Color.new(12*8,12*8,12*8) : baseColor.clone
|
|
shadow=!shadowColor ? Color.new(26*8,26*8,25*8) : shadowColor.clone
|
|
text2=text.gsub(/&/,"&")
|
|
text2.gsub!(/</,"<")
|
|
text2.gsub!(/>/,">")
|
|
text2.gsub!(/\\\[([A-Fa-f0-9]{8,8})\]/) { "<c2="+$1+">" }
|
|
text2="<c2="+colorToRgb16(base)+colorToRgb16(shadow)+">"+text2
|
|
text2.gsub!(/\\\\/,"\\")
|
|
return text2
|
|
end
|
|
|
|
# Deprecated -- not to be used in new code
|
|
def drawColoredTextEx(bitmap,x,y,width,text,_baseColor=nil,_shadowColor=nil)
|
|
chars=getFormattedText(bitmap,x,y,width,-1,coloredToFormattedText(text),32)
|
|
drawFormattedChars(bitmap,chars)
|
|
end
|
|
|
|
def pbDrawShadow(bitmap,x,y,width,height,string)
|
|
return if !bitmap || !string
|
|
pbDrawShadowText(bitmap,x,y,width,height,string,nil,bitmap.font.color)
|
|
end
|
|
|
|
def pbDrawShadowText(bitmap,x,y,width,height,string,baseColor,shadowColor=nil,align=0)
|
|
return if !bitmap || !string
|
|
width=(width<0) ? bitmap.text_size(string).width+4 : width
|
|
height=(height<0) ? bitmap.text_size(string).height+4 : height
|
|
if shadowColor && shadowColor.alpha>0
|
|
bitmap.font.color=shadowColor
|
|
bitmap.draw_text(x+2,y,width,height,string,align)
|
|
bitmap.draw_text(x,y+2,width,height,string,align)
|
|
bitmap.draw_text(x+2,y+2,width,height,string,align)
|
|
end
|
|
if baseColor && baseColor.alpha>0
|
|
bitmap.font.color=baseColor
|
|
bitmap.draw_text(x,y,width,height,string,align)
|
|
end
|
|
end
|
|
|
|
def pbDrawOutlineText(bitmap,x,y,width,height,string,baseColor,shadowColor=nil,align=0)
|
|
return if !bitmap || !string
|
|
width=(width<0) ? bitmap.text_size(string).width+4 : width
|
|
height=(height<0) ? bitmap.text_size(string).height+4 : height
|
|
if shadowColor && shadowColor.alpha>0
|
|
bitmap.font.color=shadowColor
|
|
bitmap.draw_text(x-2,y-2,width,height,string,align)
|
|
bitmap.draw_text(x,y-2,width,height,string,align)
|
|
bitmap.draw_text(x+2,y-2,width,height,string,align)
|
|
bitmap.draw_text(x-2,y,width,height,string,align)
|
|
bitmap.draw_text(x+2,y,width,height,string,align)
|
|
bitmap.draw_text(x-2,y+2,width,height,string,align)
|
|
bitmap.draw_text(x,y+2,width,height,string,align)
|
|
bitmap.draw_text(x+2,y+2,width,height,string,align)
|
|
end
|
|
if baseColor && baseColor.alpha>0
|
|
bitmap.font.color=baseColor
|
|
bitmap.draw_text(x,y,width,height,string,align)
|
|
end
|
|
end
|
|
|
|
# Draws text on a bitmap. _textpos_ is an array of text commands. Each text
|
|
# command is an array that contains the following:
|
|
# 0 - Text to draw
|
|
# 1 - X coordinate
|
|
# 2 - Y coordinate
|
|
# 3 - If true or 1, the text is right aligned. If 2, the text is centered.
|
|
# Otherwise, the text is left aligned.
|
|
# 4 - Base color
|
|
# 5 - Shadow color
|
|
# 6 - If true or 1, the text has an outline. Otherwise, the text has a shadow.
|
|
def pbDrawTextPositions(bitmap,textpos)
|
|
for i in textpos
|
|
textsize = bitmap.text_size(i[0])
|
|
x = i[1]
|
|
y = i[2]
|
|
if i[3]==true || i[3]==1 # right align
|
|
x -= textsize.width
|
|
elsif i[3]==2 # centered
|
|
x -= (textsize.width/2)
|
|
end
|
|
if i[6]==true || i[6]==1 # outline text
|
|
pbDrawOutlineText(bitmap,x,y,textsize.width,textsize.height,i[0],i[4],i[5])
|
|
else
|
|
pbDrawShadowText(bitmap,x,y,textsize.width,textsize.height,i[0],i[4],i[5])
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
|
|
#===============================================================================
|
|
# Draw images on a bitmap
|
|
#===============================================================================
|
|
def pbCopyBitmap(dstbm,srcbm,x,y,opacity=255)
|
|
rc = Rect.new(0,0,srcbm.width,srcbm.height)
|
|
dstbm.blt(x,y,srcbm,rc,opacity)
|
|
end
|
|
|
|
def pbDrawImagePositions(bitmap,textpos)
|
|
for i in textpos
|
|
srcbitmap=AnimatedBitmap.new(pbBitmapName(i[0]))
|
|
x=i[1]
|
|
y=i[2]
|
|
srcx=i[3] || 0
|
|
srcy=i[4] || 0
|
|
width=(i[5] && i[5]>=0) ? i[5] : srcbitmap.width
|
|
height=(i[6] && i[6]>=0) ? i[6] : srcbitmap.height
|
|
srcrect=Rect.new(srcx,srcy,width,height)
|
|
bitmap.blt(x,y,srcbitmap.bitmap,srcrect)
|
|
srcbitmap.dispose
|
|
end
|
|
end
|