iOS Question How to draw scaled text ?

shirlun

Active Member
Licensed User
Longtime User
Hi,

How to emulate this B4A function in B4i ? Thanks
B4X:
Dim s As Float
Dim r As Reflector
Dim v as Panel
Dim c As Canvas

v.Initialize("")
c.Initialize(v)

s = 0.9

r.Target = c
r.Target = r.GetField("paint")
r.RunMethod2("setTextScaleX", s, "java.lang.float")
 

shirlun

Active Member
Licensed User
Longtime User
What is the purpose of this code?
I want to create a Font that Character Height > Width, or Width > Height, and use this Font to draw text in a panel, how to do it in B4i ?
 
Last edited:
Upvote 0

shirlun

Active Member
Licensed User
Longtime User
There is no simple way to do draw stretched text. You can however stretch a label with a text. If you like I can show you how it is done.
Thank you,

but I must draw text to a Panel use condensed Font. In B4I Font.CreateNew I only can set Size no Width and Height. If I draw text to a bitmap then stretch it to destination that will slow down the App.

Any solution for my purpose ?
 
Upvote 0

shirlun

Active Member
Licensed User
Longtime User
Custom font is not a simple solution for me. In B4A I can do that with default Font.
Any other help is appreciate.
 
Upvote 0

shirlun

Active Member
Licensed User
Longtime User
For me, drawing scaled text is a important function for porting codes from B4A, I found the following Objective-C code, does anyone knew how to make it works for B4I Canvas or Views ?

Thanks.

#If OBJC
-(void)drawScaledString: (NSString*)string
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetTextMatrix(context,CGAffineTransformIdentity);

NSAttributedString*attrString = [self generateAttributedString:string];

CFAttributedStringSetAttribute((CFMutableAttributedStringRef)attrString,CFRangeMake(0,string.length),
kCTForegroundColorAttributeName,[UIColor redColor].CGColor);

CTLineRef line = CTLineCreateWithAttributedString((CFAttributedStringRef) attrString);

// CTLineGetTypographicBounds doesn't give correct values,
// using GetImageBounds instead

CGRect imageBounds = CTLineGetImageBounds(line, context);
CGFloat width = imageBounds.size.width;
CGFloat height = imageBounds.size.height;

CGFloat padding =0;

width += padding;
height += padding;

float sx =self.bounds.size.width / width;
float sy =self.bounds.size.height / height;

CGContextSetTextMatrix(context,CGAffineTransformIdentity);

CGContextTranslateCTM(context,1,self.bounds.size.height);
CGContextScaleCTM(context,1,-1);
CGContextScaleCTM(context, sx, sy);

CGContextSetTextPosition(context,-imageBounds.origin.x + padding/2,-imageBounds.origin.y + padding/2);

CTLineDraw(line, context);CFRelease(line);
}
#End If
 
Last edited:
Upvote 0

shirlun

Active Member
Licensed User
Longtime User
The code is not suitable for calling from B4I, but I don't know how to rewrite it.

It's great If there are some .RunMethod to set Canvas or View for drawing scaled text, above Objective-C code demonstrated the possibilities.

I already tried draw the text to a ImageView and then draw the Imageview to destination rectangle, but this method is very slow.
 
Upvote 0

shirlun

Active Member
Licensed User
Longtime User
This project can't be compiled, error message:

B4i version: 2.51
Parsing code. (0.00s)
Compiling code. (1.08s)
Compiling layouts code. (0.02s)
Compiling debugger engine code. (2.91s)
Building Xcode project (0.56s)
Sending data to remote compiler. Error
B4i line: 19
End Sub
declaration of 'kCTForegroundColorAttributeName' must be imported from module 'CoreText.CTStringAttributes' before it is required
......


B4X:
'Code module
#Region  Project Attributes 
    #ApplicationLabel: B4i Example
    #Version: 1.0.0 
    'Orientation possible values: Portrait, LandscapeLeft, LandscapeRight and PortraitUpsideDown
    #iPhoneOrientations: Portrait, LandscapeLeft, LandscapeRight
    #iPadOrientations: Portrait, LandscapeLeft, LandscapeRight, PortraitUpsideDown
    #Target: iPhone, iPad
    #MinVersion: 7
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Public App As Application
    Public NavControl As NavigationController
    Private Page1 As Page
   
End Sub

Private Sub Application_Start (Nav As NavigationController)
    NavControl = Nav
    Page1.Initialize("Page1")
    Page1.Title = "Page 1"
    Page1.RootPanel.Color = Colors.White
    NavControl.ShowPage(Page1)
End Sub

Private Sub Page1_Resize(Width As Int, Height As Int)

    Dim la As Label

    la.Initialize("")
    la.Text = ""
   
    Page1.RootPanel.Width = Width
    Page1.RootPanel.Height = Height
   
    Page1.RootPanel.AddView(la, 20,20,100,40)
   
    Dim no As NativeObject = la
   
    no.RunMethod("drawScaledString", Array("testing"))
   
End Sub

#If OBJC
- (void)drawScaledString:(NSString *)string
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetTextMatrix(context, CGAffineTransformIdentity);

    NSAttributedString *attrString = [self generateAttributedString:string];

    CFAttributedStringSetAttribute((CFMutableAttributedStringRef)attrString, CFRangeMake(0, string.length), 
                                   kCTForegroundColorAttributeName, [UIColor redColor].CGColor);

    CTLineRef line = CTLineCreateWithAttributedString((CFAttributedStringRef) attrString);

    // CTLineGetTypographicBounds doesn't give correct values, 
    // using GetImageBounds instead
    CGRect imageBounds = CTLineGetImageBounds(line, context);
    CGFloat width = imageBounds.size.width;
    CGFloat height = imageBounds.size.height;

    CGFloat padding = 0;

    width += padding;
    height += padding;

    float sx = self.bounds.size.width / width;
    float sy = self.bounds.size.height / height;

    CGContextSetTextMatrix(context, CGAffineTransformIdentity);

    CGContextTranslateCTM(context, 1, self.bounds.size.height);
    CGContextScaleCTM(context, 1, -1);
    CGContextScaleCTM(context, sx, sy);

    CGContextSetTextPosition(context, -imageBounds.origin.x + padding/2, -imageBounds.origin.y + padding/2);

    CTLineDraw(line, context);
    CFRelease(line);
}

- (NSAttributedString *)generateAttributedString:(NSString *)string
{

    CTFontRef helv = CTFontCreateWithName(CFSTR("Helvetica-Bold"),20, NULL);
    CGColorRef color = [UIColor blackColor].CGColor;

    NSDictionary *attributesDict = [NSDictionary dictionaryWithObjectsAndKeys:
                                    (id)helv, (NSString *)kCTFontAttributeName,
                                    color, (NSString *)kCTForegroundColorAttributeName,
                                    nil];

    NSAttributedString *attrString = [[[NSMutableAttributedString alloc]
                                   initWithString:string
                                        attributes:attributesDict] autorelease];

    return attrString;
}
#End If

Private Sub Application_Background
   
End Sub
 
Upvote 0

shirlun

Active Member
Licensed User
Longtime User
That line can be compiled now, but so many other error occured, seems that ObjC code must be used in a subclass.

Is there other solution to draw scaled text? Thanks.
 
Upvote 0

shirlun

Active Member
Licensed User
Longtime User
Is there any method to set the Canvas for drawing scaled text? Currently I scale the panel to make condense text, but that is not good enought since it force me to resize panels and cause new problems.
 
Upvote 0

shirlun

Active Member
Licensed User
Longtime User
Labels are not suitable to show pictures, currently I use following code to condense the panel to emulate condensed text out, it seems OK but cause some width related problems.
B4X:
Dim no As NativeObject = Me
Dim newwidth As Int = oldwidth + oldwidth * (FontH - fontW) / fontW
Dim tx As Float = (oldwidth - newwidth) / 2

FontScale = oldwidth / newwidth

no.RunMethod("SetScaleTransformation:::::", Array(hView, FontScale, 1, tx, 0))  

#if ObjC
- (void) SetScaleTransformation:(UIView*) view :(float)sx :(float)sy :(float)tx :(float)ty {
   view.transform = CGAffineTransformMakeTranslation(tx, ty);
   view.transform = CGAffineTransformScale(view.transform, sx, sy);
}
#End if
 

Attachments

  • IMG_0102.png
    IMG_0102.png
    207.9 KB · Views: 218
Upvote 0
Top