#=============================================================================== # 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("",ret) end def shadowctag(base,shadow) return sprintf("",colorToRgb16(base),colorToRgb16(shadow)) end def shadowc3tag(base,shadow) return sprintf("",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!(//,">") 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("",item.icon_name) else ix=item.icon_index % 16 * 24 iy=item.icon_index / 16 * 24 return sprintf("",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 positionwidthDst && 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=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. ... - Formats the text in bold. ... - Formats the text in italics. ... - Underlines the text. ... - Draws a strikeout line over the text. ... - Left-aligns the text. Causes line breaks before and after the text. - Right-aligns the text until the next line break. ... - Right-aligns the text. Causes line breaks before and after the text. ... - Centers the text. Causes line breaks before and after the text.
- Causes a line break. ... - Color specification. A total of four formats are supported: RRGGBBAA, RRGGBB, 16-bit RGB, and Window_Base color numbers. ... - 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 ... - 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 - Displays the text in the given opacity (0-255) Added 2009-10-19 - Displays the text in outline format. Added 2010-05-12 - Displays the text in outline format (outlines more exaggerated. ... - Formats the text in the specified font, or Arial if the font doesn't exist. ... - Changes the font size to 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 position0 && 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 xStart=0 yStart=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 || texty0) ? 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=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 then characters[i][1] = xDst + (widthDst - block[3] - 4) + characters[i][1] when 2 then 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 getLineBrokenText(bitmap,value,width,dims) x=0 y=0 textheight=0 ret=[] if dims dims[0]=0 dims[1]=0 end line=0 position=0 column=0 return ret if !bitmap || bitmap.disposed? || width<=0 textmsg=value.clone ret.push(["",0,0,0,bitmap.text_size("X").height,0,0,0,0]) while ((c = textmsg.slice!(/\n|(\S*([ \r\t\f]?))/)) != nil) break if c=="" length=c.scan(/./m).length ccheck=c if ccheck=="\n" ret.push(["\n",x,y,0,textheight,line,position,column,0]) x=0 y+=(textheight==0) ? bitmap.text_size("X").height : textheight line+=1 textheight=0 column=0 position+=length ret.push(["",x,y,0,textheight,line,position,column,0]) next end words=[ccheck] 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-2 # Zero-length word break ret.push(["",x,y,0,textheight,line,position,column,0]) x=0 column=0 y+=(textheight==0) ? bitmap.text_size("X").height : textheight line+=1 textheight=0 end textheight=[textheight,textSize.height].max ret.push([word,x,y,textwidth,textheight,line,position,column,length]) x+=textwidth dims[0]=x if dims && dims[0]]+)>/ reNoMatch=/]+>/ 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+=32 next end if ccheck[/0 && x+textwidth>width minTextSize=bitmap.text_size(word.gsub(/\s*/,"")) if x>0 && x+minTextSize.width>width x=0 y+=32 end end ret.push([word,x,y,textwidth,32,color]) x+=textwidth dims[0]=x if dims && dims[0]"+text chars=getFormattedText(bitmap,x,y,width,-1,text,lineheight) drawFormattedChars(bitmap,chars) end # Unused 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+1 : width height=(height<0) ? bitmap.text_size(string).height+1 : height y += 4 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] + 6 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 color = i[7] || nil if color srcbitmap.pbSetColorValue(color) end srcrect=Rect.new(srcx,srcy,width,height) bitmap.blt(x,y,srcbitmap.bitmap,srcrect) srcbitmap.dispose end end #added for quest log script ( edit ) def renderMultiLine(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 shadowColor height=normtext[i][4] text=normtext[i][0] bitmap.font.color=shadowColor bitmap.draw_text(textx-2,texty-2,width,height,text,0) bitmap.draw_text(textx,texty-2,width,height,text,0) bitmap.draw_text(textx+2,texty-2,width,height,text,0) bitmap.draw_text(textx-2,texty,width,height,text,0) bitmap.draw_text(textx+2,texty,width,height,text,0) bitmap.draw_text(textx-2,texty+2,width,height,text,0) bitmap.draw_text(textx,texty+2,width,height,text,0) bitmap.draw_text(textx+2,texty+2,width,height,text,0) end if baseColor height=normtext[i][4] text=normtext[i][0] bitmap.font.color=baseColor bitmap.draw_text(textx,texty,width,height,text,0) end end end def drawTextExMulti(bitmap,x,y,width,numlines,text,baseColor,shadowColor) normtext=getLineBrokenChunks(bitmap,text,width,nil,true) renderMultiLine(bitmap,x,y,normtext,numlines*32,baseColor,shadowColor) end