osx - CATextLayer gets rasterized too early and it is blurred -


i have troubles catextlayer, due me, didn't find on topic. on os x (on ios should same).

i create catextlayer layers scale factor > 1 , blurred text. layer rasterized before applying scale, think. expected behavior? hope not, because makes no sense... cashapelayer rasterized after transformation matrix applied, why catextlayer should different?

in case doing wrong... it??

catextlayer *layer = [catextlayer layer]; layer.string = @"i doing"; layer.font = (__bridge cftyperef)[nsfont systemfontofsize:24]; layer.fontsize = 24; layer.anchorpoint = cgpointzero; layer.frame = cgrectmake(0, 0, 400, 100); layer.foregroundcolor = [nscolor blackcolor].cgcolor; layer.transform = catransform3dmakescale(2., 2., 1.); layer.shouldrasterize = no; [self.layer addsublayer:layer]; 

the solution use @ moment set contentsscale property of layer scale factor. problem solution doesn't scale: if scale factor of of parent layers changes, contentsscale should updated too. should write code traverse layers tree update contentsscale properties of catextlayers... not do.

another solution, not solution, convert text shape , use cashapelayer. don't see point of having catextlayers.

a custom subclass of calayer in solving problem?

edit: cagradientlayer able render contents, cashapelayer, after transformation matrix applied. can explain how possible?

edit 2: guess paths , gradients rendered opengl display lists, rasterized @ actual size on screen opengl itself. texts rasterized core animation, bitmaps opengl.

i think go contentsscale solution moment. maybe, in future, convert texts shapes. in order best results little work, code use now:

[catransaction setdisableactions:yes];  cgfloat contentsscale = ceilf(scaleofparentlayer); // _scalabletextlayer catextlayer _scalabletextlayer.contentsscale = contentsscale; [_scalabletextlayer displayifneeded];  [catransaction setdisableactions:no]; 

after trying approaches, solution using custom subclass of calayer. don't use catextlayer @ all.

i override contentsscale property custom setter method:

- (void)setcontentsscale:(cgfloat)cs {     cgfloat scale = max(ceilf(cs), 1.); // never less 1, integer     if (scale != self.contentsscale) {         [super setcontentsscale:scale];         [self setneedsdisplay];     } } 

the value of property rounded upper integer value. when rounded value changes, layer must redrawn.

the display method of calayer subclass creates bitmap image of size of text multiplied contentsscale factor , screen scale factor.

- (void)display {     cgfloat scale = self.contentsscale * [myutils screenscale];      cgfloat width = self.bounds.size.width * scale;     cgfloat height = self.bounds.size.height * scale;      cgcontextref bitmapcontext = [myutils createbitmapcontextwithsize:cgsizemake(width, height)];      cgcontextscalectm(bitmapcontext, scale, scale);     cgcontextsetshouldsmoothfonts(bitmapcontext, 0);      ctlineref line = ctlinecreatewithattributedstring((__bridge cfattributedstringref)(_text));      cgcontextsettextposition(bitmapcontext, 0., self.bounds.size.height-_ascender);     ctlinedraw(line, bitmapcontext);     cfrelease(line);      cgimageref image = cgbitmapcontextcreateimage(bitmapcontext);     self.contents = (__bridge id)(image);     cgimagerelease(image);      cgcontextrelease(bitmapcontext); } 

when change scale factor of root layer of hierarchy, loop on text layers , set contentsscale property same factor. display method called if rounded value of scale factor changes (i.e. if previous value 1.6 , set 1.7, nothing happens. if new value 2.1, layer redisplayed).

the cost in terms of speed of redraw little. test change continuously scale factor of hierarchy of 40 text layers on 3rd gen. ipad. works butter.


Comments

Popular posts from this blog

php - Why I am getting the Error "Commands out of sync; you can't run this command now" -

linux - Does gcc have any options to add version info in ELF binary file? -

java - Are there any classes that implement javax.persistence.Parameter<T>? -