TextWidth - strange on Mac OS :-)

Mac OSX specific forum
#NULL
Addict
Addict
Posts: 1440
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

Re: TextWidth - strange on Mac OS :-)

Post by #NULL »

you can use this code to see where the kerning occurs:

Code: Select all

Procedure debugKerning(s.s)
	Protected c1.s, c2.s, w1, w2
	If Len(s) > 1
		For i=1 To Len(s)-1
			c1 = Mid(s, i, 1)
			c2 = Mid(s, i+1, 1)
			w1 = TextWidth(c1) + TextWidth(c2)
			w2 = TextWidth(c1 + c2)
			Debug c1 + c2 + " : " + Str(w2 - w1)
		Next
	EndIf
EndProcedure

;LoadFont(0, "monospace", 12)

CreateImage(1, 100, 100)
StartDrawing(ImageOutput(1))
	;DrawingFont(FontID(0))
	Debug TextWidth("Hello World")
	Debug TextWidth("H")+TextWidth("e")+TextWidth("l")+TextWidth("l")+TextWidth("o")+
	      TextWidth(" ")+TextWidth("W")+TextWidth("o")+TextWidth("r")+TextWidth("l")+TextWidth("d")
	debugKerning("Hello World")
StopDrawing()

96
97
He : 0
el : 0
ll : 0
lo : 0
o : 0
W : 0
Wo : -1
or : 0
rl : 0
ld : 0
mestnyi
Addict
Addict
Posts: 995
Joined: Mon Nov 25, 2013 6:41 am

Re: TextWidth - strange on Mac OS :-)

Post by mestnyi »

I have such results I wonder if Fred will do anything about it?
MacBook Air (13-inch, Mid 2013)

Code: Select all

61
55
He : 1
el : 1
ll : 1
lo : 1
o  : 1
 W : 0
Wo : 0
or : 1
rl : 1
ld : 1
mestnyi
Addict
Addict
Posts: 995
Joined: Mon Nov 25, 2013 6:41 am

Re: TextWidth - strange on Mac OS :-)

Post by mestnyi »

Why so slow?
It is not enough that it does not work correctly, it is also slow.
Maybe hot means api can be accelerated?

Code: Select all

;DisableDebugger

Macro PB(Function)
  Function
EndMacro

Global set_text_width.s = "_№qwertyuiopasdfghjklzxcvbnm\QWERTYUIOPASDFGHJKLZXCVBNM йцукенгшщзхъфывапролджэ\ячсмитьбю./ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭ/ЯЧСМИТЬБЮ,][{}|'+-=()*&^%$#@!±§<>`~:?0123456789"+~"\"" 

Global NewMap get_text_width.i()

Procedure SetTextWidth(Text.s, Len.i)
  Protected i, w, Key.s
  
  For i = 0 To Len 
    Key.s = Mid(Text.s, i, 1)
    
    If Not FindMapElement(get_text_width(), Key.s)
      w = PB(TextWidth)(Key)
      
      If w
        get_text_width(Key) = w
      EndIf
    EndIf
  Next
  
EndProcedure

Procedure GetTextWidth(text.s, len)
  Protected i, TextWidth.i
  
  If set_text_width
    SetTextWidth(set_text_width, Len(set_text_width))
    set_text_width = ""
  EndIf
  
  For i=1 To len
    TextWidth + get_text_width(Mid(Text.s, i, 1))
  Next
  
  ProcedureReturn TextWidth + Bool(#PB_Compiler_OS = #PB_OS_MacOS And i>1) * (i/2-1) ;Why on Mac OS should I do this?
EndProcedure

Define FontSize.CGFloat = 12.0
Global NSFont = CocoaMessage(0,0, "NSFont fontWithName:$", @"Andale Mono", "size:@", @FontSize)
Global NSDictionary = CocoaMessage(0, 0, "NSDictionary dictionaryWithObject:",  NSFont, "forKey:$", @"NSFontAttributeName")

Procedure stringWidth(string.s)
Protected NSSize.NSSize

NSString = CocoaMessage(0, 0, "NSString stringWithString:$", @string)
CocoaMessage(NSSize, NSString, "sizeWithAttributes:", NSDictionary)

ProcedureReturn NSSize\width

EndProcedure


; comment\uncomment to see resultat
; Macro TextWidth(Text) : GetTextWidth(Text, Len(Text)) : EndMacro
; Macro TextWidth(Text) : stringWidth(Text) : EndMacro

 
Procedure.s Wrap (Text.s, Width.i)
  Protected.i CountString, i, start, ii, found, length
  Protected line$, ret$="", LineRet$="", TextWidth
  
  CountString = CountString(Text.s, #LF$) 
  
  For i = 1 To CountString
    line$ = StringField(Text.s, i, #LF$)
    start = Len(line$)
    length = start
    
    ; Get text len
    While length > 1
       ; Debug ""+TextWidth(RTrim(Left(Line$, length))) +" "+ GetTextWidth(RTrim(Left(Line$, length)), length) +" "+ stringWidth(RTrim(Left(Line$, length)))
      If width > TextWidth(RTrim(Left(Line$, length))) 
        Break
      Else
        length - 1
      EndIf
    Wend 
    
    While start > length 
      start = length
      
      LineRet$ + Left(line$, start) + #LF$
      line$ = LTrim(Mid(line$, start+1))
      start = Len(line$)
      length = start
      
      ; Get text len
      While length > 1
        If width > TextWidth(RTrim(Left(Line$, length)))
          Break
        Else
          length - 1
        EndIf
      Wend 
      
    Wend   
    
    ret$ + LineRet$ + line$ + #CRLF$
    LineRet$=""
  Next
  
  ProcedureReturn ret$
EndProcedure

Global Text.s = "строка_1"+Chr(10)+
"строка__2"+Chr(10)+
"строка___3 эта длинняя строка оказалась ну, очень длинной, поэтому будем его переносить"+Chr(10)+
"строка_4"+#CRLF$+
"строка__5"+#LF$


If OpenWindow(0, 0, 0, 220, 620, "CanvasGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CanvasGadget(0, 10, 10, 200, 600)
  
  If StartDrawing(CanvasOutput(0))
    Box(0,0,OutputWidth(), OutputHeight(), $FFFFFF)
    h=TextHeight("A")
    
    time = ElapsedMilliseconds()
    Text = Wrap(Text.s, 10)
    
    If (#PB_Compiler_OS = #PB_OS_Windows)
      count = CountString(Text.s, #LF$)
      For i=1 To count
        String.s = StringField(Text.s, i, #LF$)
        DrawText(10,i*h+10,String.s, $000000, $FFFFFF)
      Next  
    Else
      DrawText(10,10,Text.s, $000000, $FFFFFF)
    EndIf
    time = ElapsedMilliseconds()-time
    
    StopDrawing() 
  EndIf
  MessageRequester( "", Str(time) )
  
  Repeat
    Event = WaitWindowEvent()
  Until Event = #PB_Event_CloseWindow
EndIf

;   result 
;   75 21
;   21 31
mestnyi
Addict
Addict
Posts: 995
Joined: Mon Nov 25, 2013 6:41 am

Re: TextWidth - strange on Mac OS :-)

Post by mestnyi »

Who knows how to draw text and get the width of the text using api tools?
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: TextWidth - strange on Mac OS :-)

Post by wilbert »

mestnyi wrote:Who knows how to draw text and get the width of the text using api tools?
Take a look at the Apple docs for NSString.

Here's a drawing example but be aware coordinate (0,0) is bottom left instead of top left.

Code: Select all

#NSItalicFontMask = 1
FontManager = CocoaMessage(0, 0, "NSFontManager sharedFontManager")

FontSize.CGFloat = 12
BoldItalicFont = CocoaMessage(0, FontManager, "fontWithFamily:$", @"Helvetica",
                            "traits:", #NSItalicFontMask, 
                            "weight:", 9, "size:@", @FontSize)

AttrBlueItalic = CocoaMessage(0, 0, "NSMutableDictionary new")
CocoaMessage(0, AttrBlueItalic, "setValue:", CocoaMessage(0, 0, "NSColor blueColor"), "forKey:$", @"NSColor")
CocoaMessage(0, AttrBlueItalic, "setValue:", BoldItalicFont, "forKey:$", @"NSFont")

AttrRed = CocoaMessage(0, 0, "NSMutableDictionary new")
CocoaMessage(0, AttrRed, "setValue:", CocoaMessage(0, 0, "NSColor redColor"), "forKey:$", @"NSColor")


OpenWindow(0, 0, 0, 220, 220, "CanvasGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(0, 10, 10, 200, 200)

S.s = "Hello, let's draw this line of text"
NSString = CocoaMessage(0, 0, "NSString stringWithString:$", @S)

Point.NSPoint\x = 10
Point\y = 10

Rect.NSRect\origin\x = 20
Rect\origin\y = 60
Rect\size\width = 160
Rect\size\height = 50 


StartDrawing(CanvasOutput(0))
CocoaMessage(0, NSString, "drawAtPoint:@", @Point, "withAttributes:", AttrRed)
CocoaMessage(0, NSString, "drawInRect:@", @Rect, "withAttributes:", AttrBlueItalic)
StopDrawing()

Repeat
  Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
Windows (x64)
Raspberry Pi OS (Arm64)
mestnyi
Addict
Addict
Posts: 995
Joined: Mon Nov 25, 2013 6:41 am

Re: TextWidth - strange on Mac OS :-)

Post by mestnyi »

wilbert
Thank you, very interesting, I delve into this matter. :)
What about getting the width and height of the text?
mestnyi
Addict
Addict
Posts: 995
Joined: Mon Nov 25, 2013 6:41 am

Re: TextWidth - strange on Mac OS :-)

Post by mestnyi »

I tried to translate it into understandable form, but it seems that they behave differently.

Code: Select all

OpenWindow(0, 0, 0, 220, 220, "CanvasGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(0, 10, 10, 200, 200)

S.s = "Hello, let's draw this line of text"

Procedure DrawText_(x, y, Text.s, FrontColor.i=0)
  Protected Point.NSPoint
  Point\x = x
  Point\y = OutputHeight()-TextHeight("A")-y
  Protected AttrRed
  Protected NSString
  
 If FrontColor
    AttrRed = CocoaMessage(0, 0, "NSMutableDictionary new")
    CocoaMessage(0, AttrRed, "setValue:", CocoaMessage(0, 0, "NSColor redColor"), "forKey:$", @"NSColor")
  EndIf
  
  NSString = CocoaMessage(0, 0, "NSString stringWithString:$", @Text)
  CocoaMessage(0, NSString, "drawAtPoint:@", @Point, "withAttributes:", AttrRed)
EndProcedure


StartDrawing(CanvasOutput(0))

ClipOutput( 10,6,200,100)

DrawText_(100,10, "os draw text");, $FFFF3B00)
DrawText(10,10, "pb draw text");, $FFFF3B00)

StopDrawing()

Repeat
  Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: TextWidth - strange on Mac OS :-)

Post by wilbert »

mestnyi wrote:I tried to translate it into understandable form, but it seems that they behave differently.
In what way do they behave differently ?

This is more like PB with both front and back color

Code: Select all

OpenWindow(0, 0, 0, 220, 220, "CanvasGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(0, 10, 10, 200, 200)

S.s = "Hello, let's draw this line of text"

Procedure ClipOutput_(x, y, width, height)
  Protected Rect.NSRect
  Rect\origin\x = x : Rect\origin\y = OutputHeight()-height-y
  Rect\size\width = width : Rect\size\height = height
  CocoaMessage(0, CocoaMessage(0, 0, "NSBezierPath bezierPathWithRect:@", @Rect), "setClip")
EndProcedure

Procedure DrawText_(x, y, Text.s, FrontColor=$ffffff, BackColor=0)
  Protected.CGFloat r,g,b,a
  Protected.i NSString, Attributes, Color
  Protected Size.NSSize, Point.NSPoint
  
  CocoaMessage(@Attributes, 0, "NSMutableDictionary dictionaryWithCapacity:", 2)
  
  r = Red(FrontColor)/255 : g = Green(FrontColor)/255 : b = Blue(FrontColor)/255 : a = 1
  Color = CocoaMessage(0, 0, "NSColor colorWithDeviceRed:@", @r, "green:@", @g, "blue:@", @b, "alpha:@", @a)
  CocoaMessage(0, Attributes, "setValue:", Color, "forKey:$", @"NSColor")
  
  r = Red(BackColor)/255 : g = Green(BackColor)/255 : b = Blue(BackColor)/255 : a = 1
  Color = CocoaMessage(0, 0, "NSColor colorWithDeviceRed:@", @r, "green:@", @g, "blue:@", @b, "alpha:@", @a)
  CocoaMessage(0, Attributes, "setValue:", Color, "forKey:$", @"NSBackgroundColor")  
  
  NSString = CocoaMessage(0, 0, "NSString stringWithString:$", @Text)
  CocoaMessage(@Size, NSString, "sizeWithAttributes:", Attributes)
  Point\x = x : Point\y = OutputHeight()-Size\height-y
  CocoaMessage(0, NSString, "drawAtPoint:@", @Point, "withAttributes:", Attributes)
EndProcedure


StartDrawing(CanvasOutput(0))

ClipOutput_(10,6,200,100)

DrawText_(100,10, "os draw text");, $FFFF3B00)
DrawText(10,10, "pb draw text");, $FFFF3B00)

StopDrawing()

Repeat
  Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
Windows (x64)
Raspberry Pi OS (Arm64)
mestnyi
Addict
Addict
Posts: 995
Joined: Mon Nov 25, 2013 6:41 am

Re: TextWidth - strange on Mac OS :-)

Post by mestnyi »

wilbert You are just a magician. :shock:
mestnyi wrote:What about getting the width and height of the text?
If and help me lucky. :)
I look api apple I do not find similarities how do you implement purebasic?
Post Reply