首页 > 其他分享 >富文本转路径

富文本转路径

时间:2023-04-12 14:57:50浏览次数:48  
标签:rt 0.0 路径 lineRun CFIndex lineRunIndex 文本 ascent

+ (UIBezierPath *)attributedString2BezierPath:(NSAttributedString *)attributedString inBounds:(CGSize)bounds {
    NSString *clearText = attributedString.string;
    NSCharacterSet *ignoredCharsSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];
    if ([clearText stringByTrimmingCharactersInSet:ignoredCharsSet].length == 0) {
        return [UIBezierPath bezierPath];
    }
    CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)attributedString);
    CFRange textRange = CFRangeMake(0, attributedString.length);
    CGSize frameSize = CTFramesetterSuggestFrameSizeWithConstraints(frameSetter, textRange, NULL, bounds, NULL);
    CGPathRef framePath = [UIBezierPath bezierPathWithRect:CGRectMake(0.0, 0.0, frameSize.width, frameSize.height)].CGPath;
    CTFrameRef frame = CTFramesetterCreateFrame(frameSetter, textRange, framePath, NULL);
    CGMutablePathRef path = CGPathCreateMutable();
    CFArrayRef lines = CTFrameGetLines(frame);
    CGFloat linesShift = 0.0;
    CFIndex lineCount = CFArrayGetCount(lines);
    CGPoint origins[lineCount];
    CTFrameGetLineOrigins(frame, CFRangeMake(0, lineCount), origins);
    for (CFIndex index = 0; index < lineCount; index++) {
        CTLineRef line = CFArrayGetValueAtIndex(lines, index);
        CGPoint lineOrigin = origins[index];
        CGFloat ascent, descent, leading;
        CTLineGetTypographicBounds(line, &ascent, &descent, &leading);
        CFArrayRef lineRuns = CTLineGetGlyphRuns(line);
        CGFloat effectiveDescent = 0.0;
        CGFloat effectiveAscent = 0.0;
        CFIndex lineRunCount = CFArrayGetCount(lineRuns);
        for (CFIndex lineRunIndex = 0; lineRunIndex < lineRunCount; lineRunIndex++) {
            CTRunRef lineRun = CFArrayGetValueAtIndex(lineRuns, lineRunIndex);
            CFIndex glyphsCount = CTRunGetGlyphCount(lineRun);
            if (glyphsCount == 0) {
                continue;
            }
            CGFloat rt_ascent = 0.0;
            CGFloat rt_descent = 0.0;
            CGFloat rt_leading = 0.0;
            CTRunGetTypographicBounds(lineRun, CFRangeMake(0, glyphsCount), &rt_ascent, &rt_descent, &rt_leading);
            effectiveAscent = MAX(effectiveAscent, ABS(rt_ascent));
            effectiveDescent = MAX(effectiveDescent, ABS(rt_descent));
        }
        for (CFIndex lineRunIndex = 0; lineRunIndex < lineRunCount; lineRunIndex++) {
            CTRunRef lineRun = CFArrayGetValueAtIndex(lineRuns, lineRunIndex);
            CFIndex glyphsCount = CTRunGetGlyphCount(lineRun);
            if (glyphsCount == 0) {
                continue;
            }
            NSDictionary *attributes = (__bridge NSDictionary *)CTRunGetAttributes(lineRun);
            UIFont *font = attributes[NSFontAttributeName] ?: [UIFont systemFontOfSize:UIFont.systemFontSize];
            const CGGlyph *glyphPtr = CTRunGetGlyphsPtr(lineRun);
            const CGPoint *positionPtr = CTRunGetPositionsPtr(lineRun);
            for (CFIndex glyphIndex = 0; glyphIndex < glyphsCount; glyphIndex++) {
                CGGlyph glyph = glyphPtr[glyphIndex];
                CGPoint gPosition = positionPtr[glyphIndex];
                CGAffineTransform T = CGAffineTransformMakeScale(1, 1);
                CTFontRef ctFont = (__bridge CTFontRef)(font);
                CGPathRef glyphPath = CTFontCreatePathForGlyph(ctFont, glyph, &T);
                if (glyphPath != NULL) {
                    CGRect pathBounds = CGPathGetBoundingBox(glyphPath);
                    CGAffineTransform pathOffset = CGAffineTransformMakeTranslation(-pathBounds.origin.x, -pathBounds.origin.y);
                    CGPathRef glyphPathRel = CGPathCreateCopyByTransformingPath(glyphPath, &pathOffset);
                    if (glyphPathRel == NULL) {
                        glyphPathRel = glyphPath;
                    }
                    CGPoint position = CGPointMake(lineOrigin.x + gPosition.x + pathBounds.origin.x, lineOrigin.y + gPosition.y + pathBounds.origin.y);
                    CGPoint offset = CGPointMake(position.x, position.y + (ascent - effectiveAscent) + linesShift);
                    CGAffineTransform PT = CGAffineTransformMakeTranslation(offset.x, offset.y);
                    CGPathAddPath(path, &PT, glyphPathRel);
                    if (glyphPathRel != glyphPath) {
                        CGPathRelease(glyphPathRel);
                    }
                    CFRelease(glyphPath);
                }
            }
        }
        linesShift += (ascent + descent) - (effectiveAscent + effectiveDescent);
    }
    CGAffineTransform matrix = CGAffineTransformMakeScale(1, -1);
    matrix = CGAffineTransformTranslate(matrix, 0.0, -frameSize.height);
    CGPathRef finalPath = CGPathCreateMutableCopyByTransformingPath(path, &matrix);
    CFRelease(frameSetter);
    CFRelease(frame);
    CFRelease(path);
    UIBezierPath *resultPath = [UIBezierPath bezierPathWithCGPath:finalPath];
    CGPathRelease(finalPath);
    return resultPath;
}

 

标签:rt,0.0,路径,lineRun,CFIndex,lineRunIndex,文本,ascent
From: https://www.cnblogs.com/yuxiaoyiyou/p/17309781.html

相关文章

  • python爬虫(四):文本、图片、视频爬取实例
    上篇讲了常用的python爬虫工具,可以快速支撑我们数据的爬取--解析--分析,这里将拆解几个爬虫程序实例进行学习,实例来自于https://cuijiahua.com/blog/2020/04/spider-6.html的系列教程或者其他小爬虫;一、文本图表数据抓取(编程语言排名)#!/usr/bin/envpython#coding:utf-8importr......
  • 【C++】统计文本词频程序
    1#include<iostream>2#include<fstream>3#include<string>4#include<iomanip>5#include<vector>6#include<map>7#include<cctype>8#include<algorithm>9boolcmp(std::pair<std::strin......
  • R语言中实现sem进行结构方程建模和路径图可视化|附代码数据
    原文链接:http://tecdat.cn/?p=23312最近我们被客户要求撰写关于结构方程建模的研究报告,包括一些图形和统计输出。结构方程模型是一个线性模型框架,它对潜变量同时进行回归方程建模引言 诸如线性回归、多元回归、路径分析、确认性因子分析和结构回归等模型都可以被认为是SEM的......
  • SpringBoot实现文件图片上传并转换为虚拟路径
    页面代码<!DOCTYPEhtml><htmllang="en"xmlns:th="http://www.thymeleaf.org"><head><metacharset="UTF-8"><title>Title</title></head><body><formaction="/putpic......
  • css steps实现文本一个字一个字显示
    大致思路:使用相对定位的div覆盖文本内容,并用animation控制宽度,位置。换行步骤在外层div上控制高度即可。css的steps与animation一起使用可以控制文字单个显示,类似于文本输入,不过显示频率是线性。添加一些css变量控制步骤宽度、高度和时间等,便于vue中也通过组件的props......
  • 文本摘要热点及发展方向(?)
    热点:2019:摘要定制化的预训练模型不同场景的数据集学术论文摘要生成式摘要的事实一致性方向:模仿人撰写摘要的模式,融合抽取式和生成式摘要方法生成联合摘要基于语义层面研究进一步地深度挖掘句子级、篇章级的语义并加以利用来进一步提高文本摘要的语义一致性和可读性定制......
  • 利用强化学习Q-Learning实现最短路径算法
    如果你是一名计算机专业的学生,有对图论有基本的了解,那么你一定知道一些著名的最优路径解,如Dijkstra算法、Bellman-Ford算法和a*算法(A-Star)等。这些算法都是大佬们经过无数小时的努力才发现的,但是现在已经是人工智能的时代,强化学习算法能够为我们提出和前辈一样好的解决方案吗?......
  • python文本转语音库Pyttsx3
    python文本转语音库Pyttsx3:https://github.com/nateshmbhat/pyttsx3Installation:pipinstallpyttsx3Linuxinstallationrequirements:Ifyouareonalinuxsystemandifthevoiceoutputisnotworking,then:Installespeak,ffmpegandlibespeak1asshown......
  • 编辑大量文本的情况vscode比notepad++性能更好
    尝试操作几十万行的文本的时候Notepad++直接卡死了二十多万行的文本选中需要卡几秒,剪切粘贴文本需要卡几秒文本替换需要跑几十秒,再多一些的话容易卡崩 使用vscode进行剪切粘贴批量替换之类的操作基本是不卡秒执行的 一次性选中多行的方法:使用ctrl+G可以跳转到指定行ct......
  • 翻译文本 API说明示例
    t_text-翻译文本名称 类型 必须 描述key String 是 调用key(必须以GET方式拼接在URL中)secret String 是 调用密钥(获取key和secret)api_name String 是 API接口名称(包括在请求地址中)[item_search,item_get,item_search_shop等]cache String 否 [yes,no]默认yes,将调用缓存的数据,速度比......