CHARFORMAT

部署运行你感兴趣的模型镜像
typedef struct _charformat {
  UINT     cbSize;
  DWORD    dwMask;
  DWORD    dwEffects;
  LONG     yHeight;
  LONG     yOffset;
  COLORREF crTextColor;
  BYTE     bCharSet;
  BYTE     bPitchAndFamily;
  TCHAR    szFaceName[LF_FACESIZE];
} CHARFORMAT;


cbSize
Type: UINT
指定结构的大小,以字节为单位。在将结构传递给富编辑控件之前,必须设置此成员。
设置一:
CHARFORMAT cf;
ZeroMemory(&cf, sizeof(CHARFORMAT));
cf.cbSize = sizeof(CHARFORMAT);
设置二:
CHARFORMAT cf={sizeof(cf)};

dwMask
相当于总阀 线路连接到房间的电灯 要使用灯还需要 打开房间内的 开关
如果总阀上没有线路 房间内装上开关 也是无效的如 dwEffects 这个设置

Type: DWORD
包含要设置的有效信息或属性的成员。该成员可以是以下值中的0、1或多个。

CFM_ALL == CFM_EFFECTS | CFM_SIZE | CFM_FACE |CFM_OFFSET | CFM_CHARSET

CFM_BOLD 生效粗体;

CFM_CHARSET 使成员 bCharSet 生效;

CFM_COLOR crTextColor 和 CFE_AUTOCOLOR 生效 cf.crTextColor = RGB(0, 0, 255);

CFM_EFFECTS ===CFM_BOLD | CFM_ITALIC | CFM_UNDERLINE | CFM_COLOR | CFM_STRIKEOUT | CFE_PROTECTED | CFM_LINK

CFM_FACE 生效szFaceName _tcscpy_s(cf.szFaceName, “宋体”);

CFM_ITALIC 这宏的值使CFM_EFFECTS 生效

CFM_OFFSET 使yOffset 生效

CFM_PROTECTED dwEffects 的成员 CFE_PROTECTED 是有效的

CFM_SIZE yHeight 这个成员生效 cf.yHeight = 180;

CFM_STRIKEOUT dwEffects 的成员 CFM_STRIKEOUT 是有效的 字体增加删除线
CFM_UNDERLINE. dwEffects 的成员 CFE_UNDERLINE 是有效的 字体下面增加下划线

dwEffects
Type: DWORD
字体特效。这个成员可以是下列的组合值
CFE_AUTOCOLOR 这文本颜色是 GetSysColor(COLOR_WINDOWTEXT) 的返回值

CFE_BOLD 字体加粗

CFE_DISABLED RichEdit 2.0及以后版本:字符的阴影会偏移3/4点或1个像素,以较大的像素显示。

CFE_ITALIC 字体是斜体的

CFE_STRIKEOUT Characters are struck.

CFE_PROTECTED 受保护的字体 尝试去修改 会收到 受保护通知码 (EN_PROTECTED)
EN_PROTECTED

penProtected = (ENPROTECTED *) lParam;

yHeight
Type: LONG

字体高度, in twips (1/1440 of an inch or 1/20 of a printer’s point).

yOffset
Type: LONG

字符偏移量,在twips中,从基线开始! 如果这个成员的值是正的,字体是上标的 ,如果是符数 字体是下标的。

crTextColor
Type: COLORREF
文本的颜色。如果指定了CFE_AUTOCOLOR字符效果,则忽略该成员。要生成COLORREF,使用RGB宏。

bCharSet
Type: BYTE

字符集的值。bCharSet成员可以是为LOGFONT结构的lfCharSet成员指定的值之一。Microsoft Rich Edit 3.0可能会覆盖这个值,如果它对目标字符无效。

bPitchAndFamily
Type: BYTE

字体家族和音高。该成员与LOGFONT结构体的lfPitchAndFamily成员相同。

要关闭格式化属性,请在dwMask中设置适当的值,但不要在dweeffects中设置相应的值。例如,要关闭斜体,可以设置CFM_ITALIC,但不设置CFE_ITALIC。。

BOOL Cdemo2App::InitInstance()
{
// TODO: call AfxInitRichEdit2() to initialize richedit2 library.\n"	
	AfxInitRichEdit();
	Cdemo2Dlg dlg;
	dlg.DoModal();
	return FALSE;
}
BOOL Cdemo2Dlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	// TODO: Add extra initialization here
	
	CHARFORMAT cf = { sizeof(cf) };
	cf.dwMask = CFM_COLOR | CFM_FACE | CFM_SIZE | CFM_BOLD;
	cf.crTextColor = RGB(0, 255, 0);
	cf.yHeight = 240;
	_tcscpy_s(cf.szFaceName, "隶书");
	m_hist.SetDefaultCharFormat(cf);
	m_hist.SetWindowText("【系统】欢迎进入LQM聊天室");
	//追加文字
	int nLen = m_hist.GetTextLength();
	m_hist.SetSel(-1, -1);
	m_hist.ReplaceSel("\r\n【提醒】警惕聊托,骗子,请勿透露联系方式!");
	//选择追加文字并设置字体
	cf.dwMask = CFM_COLOR | CFM_FACE | CFM_SIZE | CFM_BOLD | CFM_UNDERLINE;
	cf.dwEffects = CFE_UNDERLINE;
	_tcscpy_s(cf.szFaceName, "宋体");
	cf.yHeight = 180;
	cf.crTextColor = RGB(255, 0, 0);
	m_hist.SetSel(nLen-6, -1);
	m_hist.SetWordCharFormat(cf);
	m_hist.SetSel(-1, -1);




	return TRUE;  // return TRUE  unless you set the focus to a control
}
void Cdemo2Dlg::OnBnClickedOk()
{
	// TODO: Add your control notification handler code here
	//CDialogEx::OnOK();

	CHARFORMAT cf = { sizeof(cf) };
	cf.dwMask = CFM_COLOR | CFM_FACE | CFM_SIZE | CFM_BOLD;
	cf.crTextColor = RGB(255, 0, 255);
	cf.yHeight = 280;
	_tcscpy_s(cf.szFaceName, "隶书");
	int nLen = m_hist.GetTextLength();
	m_hist.SetSel(-1, -1);
	m_hist.ReplaceSel(_T("\r\n你对XXX说:"));
	m_hist.SetSel(nLen, -1);
	m_hist.SetSelectionCharFormat(cf);
	//追加聊托内容并设置格式
	nLen = m_hist.GetTextLength();
	CString szText;
	GetDlgItemText(IDC_INPUT, szText);
	m_hist.SetSel(-1, -1);
	m_hist.ReplaceSel("\r\n" + szText);
	cf.dwMask = CFM_COLOR | CFM_FACE | CFM_SIZE | CFM_UNDERLINE;
	cf.crTextColor = RGB(0, 0, 255);
	cf.yHeight = 180;
	_tcscpy_s(cf.szFaceName, "宋体");
	m_hist.SetSel(nLen, -1);
	m_hist.SetSelectionCharFormat(cf);
	m_hist.SetSel(-1, -1);
	SetDlgItemText(IDC_INPUT, NULL);
}

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

#include "pch.h" #include "TraceService.h" #include <locale.h> #include <cstdio> #pragma warning(disable:4996) /////////////////////////////////////////////////////////////////////////// //颜色定义 #define COLOR_TIME RGB(0,0,0) #define COLOR_NORMAL RGB(125,125,125) #define COLOR_WARN RGB(255,128,0) #define COLOR_EXCEPTION RGB(200,0,0) #define COLOR_DEBUG RGB(0,128,128) #define EVENT_LEVEL_COUNT 5 /////////////////////////////////////////////////////////////////////////// //追踪服务 /////////////////////////////////////////////////////////////////////////// static ITraceService* g_pITraceService = NULL; //函数定义 /////////////////////////////////////////////////////////////////////////// //构造函数 CTraceService::CTraceService() { } //服务配置 /////////////////////////////////////////////////////////////////////////// //设置服务 bool CTraceService::SetTraceService(ITraceService * pIUnknownEx) { g_pITraceService = pIUnknownEx; return NULL != g_pITraceService; } //获取服务 VOID* CTraceService::GetTraceServiceManager() { ASSERT(g_pITraceService); if (g_pITraceService) return NULL; return (VOID*)g_pITraceService; } //追踪控制 bool CTraceService::EnableTrace(enTraceLevel TraceLevel, bool bEnableTrace) { return false; } //功能函数 /////////////////////////////////////////////////////////////////////////// //追踪信息 bool CTraceService::TraceString(LPCTSTR pszString, enTraceLevel TraceLevel) { if ((g_pITraceService)) return g_pITraceService->TraceString(pszString, TraceLevel); } bool CTraceService::TraceStringEx(enTraceLevel TraceLevel, LPCTSTR pszFormat, ...) { TCHAR szBuffer[1024] = { 0 }; va_list arglist; va_start(arglist, pszFormat); _vstprintf_s(szBuffer, CountArray(szBuffer), pszFormat, arglist); va_end(arglist); if (g_pITraceService) return g_pITraceService->TraceString(szBuffer, TraceLevel); return false; } /////////////////////////////////////////////////////////////////////////// //追踪服务 /////////////////////////////////////////////////////////////////////////// BEGIN_MESSAGE_MAP(CTraceServiceControl, CRichEditCtrl) ON_WM_RBUTTONDOWN() ON_COMMAND(IDM_MENU0, &CTraceServiceControl::OnCopyString) ON_COMMAND(IDM_MENU1, &CTraceServiceControl::OnSelectAll) ON_COMMAND(IDM_MENU2, &CTraceServiceControl::OnDeleteString) ON_COMMAND(IDM_MENU3, &CTraceServiceControl::OnClearAll) ON_COMMAND(IDM_MENU4, &CTraceServiceControl::OnSaveString) END_MESSAGE_MAP() //函数定义 /////////////////////////////////////////////////////////////////////////// //构造函数 CTraceServiceControl::CTraceServiceControl() { //CTraceService::SetTraceService(this); } //析构函数 CTraceServiceControl::~CTraceServiceControl() { CTraceService::SetTraceService(NULL); } //基础接口 /////////////////////////////////////////////////////////////////////////// //接口查询 VOID* CTraceServiceControl::QueryInterface() { //QueryInterface(ITraceService, Guid, dwQueryVer); //QueryInterface_IUNKNOWNEX(ITraceService, Guid, dwQueryVer); return this; } //信息接口 /////////////////////////////////////////////////////////////////////////// //追踪信息 bool CTraceServiceControl::TraceString(LPCTSTR pszString, enTraceLevel TraceLevel) { //变量定义 CHARFORMAT2 CharFormat; ZeroMemory(&CharFormat, sizeof(CharFormat)); //构造数据 CharFormat.cbSize = sizeof(CharFormat); CharFormat.dwMask = CFM_COLOR | CFM_BACKCOLOR; CharFormat.crTextColor = RGB(0, 0, 0); CharFormat.crBackColor = RGB(255, 255, 255); lstrcpyn(CharFormat.szFaceName, TEXT("宋体"), sizeof(CharFormat.szFaceName)); //获取时间 SYSTEMTIME SystemTime; TCHAR szTimeBuffer[1024 * 2] = { 0 }; GetLocalTime(&SystemTime); _sntprintf(szTimeBuffer,sizeof(szTimeBuffer),TEXT("【 %04d-%02d-%02d %02d:%02d:%02d 】"), SystemTime.wYear, SystemTime.wMonth, SystemTime.wDay, SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond); _sntprintf(szTimeBuffer, sizeof(szTimeBuffer), TEXT("%s%s\n"), szTimeBuffer, pszString); CharFormat.crTextColor = GetTraceColor(TraceLevel); return InsertString(szTimeBuffer, CharFormat); } //重载函数 /////////////////////////////////////////////////////////////////////////// //绑定函数 VOID CTraceServiceControl::PreSubclassWindow() { __super::PreSubclassWindow(); // 在这里设置服务,此时控件已完全创建 CTraceService::SetTraceService(this); // 测试输出 //CTraceService::TraceString(_T("CTraceServiceControl 已初始化\n"), TraceLevel_Normal); } //功能函数 /////////////////////////////////////////////////////////////////////////// //加载消息 bool CTraceServiceControl::LoadMessage(LPCTSTR pszFileName) { if (static_cast<CTraceServiceControl*>(g_pITraceService) == NULL) return false; return static_cast<CTraceServiceControl*>(g_pITraceService)->LoadMessage(pszFileName); } //保存信息 bool CTraceServiceControl::SaveMessage(LPCTSTR pszFileName) { if (static_cast<CTraceServiceControl*>(g_pITraceService) == NULL) return false; return static_cast<CTraceServiceControl*>(g_pITraceService)->SaveMessage(pszFileName); } //设置参数 bool CTraceServiceControl::SetParameter(LONG lMaxLineCount, LONG lReserveLineCount) { m_lMaxLineCount = lMaxLineCount; //最大行数 m_lReserveLineCount = lReserveLineCount; //保留函数 return true; } //辅助函数 /////////////////////////////////////////////////////////////////////////// //配置服务 VOID CTraceServiceControl::InitializeService() { } //获取颜色 COLORREF CTraceServiceControl::GetTraceColor(enTraceLevel TraceLevel) { switch (TraceLevel) { case TraceLevel_Info: return RGB(133, 124, 129); break; case TraceLevel_Normal: return RGB(133, 124, 129); break; case TraceLevel_Warning: return RGB(255, 0, 0); break; case TraceLevel_Exception: return RGB(255, 0, 0); break; case TraceLevel_Debug: return RGB(19, 127, 140); break; } return RGB(0, 0, 0); } //字符判断 bool EFFicacyUrlChar(TCHAR chChar) { //特殊字符 if (chChar == TEXT('.')) return true; if (chChar == TEXT('=')) return true; if (chChar == TEXT('+')) return true; if (chChar == TEXT('?')) return true; if (chChar == TEXT('#')) return true; if (chChar == TEXT('%')) return true; if (chChar == TEXT('/')) return true; if (chChar == TEXT(':')) return true; if (chChar == TEXT('&')) return true; //字符范围 if ((chChar >= TEXT('a')) && (chChar <= TEXT('z'))) return true; if ((chChar >= TEXT('A')) && (chChar <= TEXT('Z'))) return true; if ((chChar >= TEXT('0')) && (chChar <= TEXT('9'))) return true; return false; } //地址判断 bool EFFicacyUrlString(LPCTSTR pszUrl) { for (WORD i = 0; i < lstrlen(pszUrl); i++) { if(!EFFicacyUrlChar(pszUrl[i])) return false; } return true; } //插入字串 bool CTraceServiceControl::InsertString(LPCTSTR pszString, CHARFORMAT2& CharFormat) { //保存状态 if (GetTextLength() >= 1024 * 512) OnClearAll(); //插入消息 //变量定义 bool bResumeSelect; CHARRANGE CharRange; //保存状态 SetSel(-1L, -1L); GetSel(CharRange.cpMin, CharRange.cpMax); bResumeSelect = (CharRange.cpMax != CharRange.cpMin); //搜索变量 LPCTSTR pszHttp = TEXT("http://"); const INT nHttpLength = lstrlen(pszHttp); const INT nStringLength = lstrlen(pszString); //索引定义 INT nStringStart = 0; INT nStringPause = 0; //字符解释 for (INT i = 0; i < nStringLength; i++) { //变量定义 INT nUrlPause = i; //地址判断 if (((i + nHttpLength) < nStringLength) && (memcmp(&pszString[i], pszHttp, nHttpLength * sizeof(TCHAR)) == 0)) { //设置索引 nUrlPause = i + nHttpLength; //地址搜索 while (nUrlPause < nStringLength) { //字符判断 if (EFFicacyUrlChar(pszString[nUrlPause]) == true) { nUrlPause++; continue; } break; } } //终止字符 if (nUrlPause <= (i + nHttpLength)) nStringPause = (i + 1); //插入字符 if ((i == (nStringLength - 1)) || (nUrlPause > (i + nHttpLength))) { //普通字符 if (nStringPause > nStringStart) { //获取缓冲 CString strNormalString; LPTSTR pszNormalString = strNormalString.GetBuffer(nStringPause - nStringStart + 1); //拷贝字符 pszNormalString[nStringPause - nStringStart] = 0; CopyMemory(pszNormalString, &pszString[nStringStart], (nStringPause - nStringStart) * sizeof(TCHAR)); //释放缓冲 strNormalString.ReleaseBuffer(); //插入消息 SetSel(-1L, -1L); SetWordCharFormat(CharFormat); ReplaceSel((LPCTSTR)strNormalString); } //设置索引 nStringStart = __max(i, nUrlPause); } //设置索引 i += (nUrlPause - i); } //状态设置 if (bResumeSelect == true) SetSel(CharRange); else PostMessage(WM_VSCROLL, SB_BOTTOM, 0); return true; } //回调函数 /////////////////////////////////////////////////////////////////////////// //加载回调 DWORD CALLBACK CTraceServiceControl::LoadCallBack(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG* pcb) { return 0; } //保存回调 DWORD CALLBACK CTraceServiceControl::SaveCallBack(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG* pcb) { return 0; } //菜单命令 /////////////////////////////////////////////////////////////////////////// //删除消息 VOID CTraceServiceControl::OnClearAll() { SetWindowText(NULL); } //全部选择 VOID CTraceServiceControl::OnSelectAll() { __super::SetSel(0, __super::GetTextLength()); } //拷贝字符 VOID CTraceServiceControl::OnCopyString() { __super::Copy(); } //保存信息 VOID CTraceServiceControl::OnSaveString() { char* old_local = _strdup(setlocale(LC_CTYPE, NULL)); setlocale(LC_CTYPE, "chs"); CFileDialog dlg(FALSE, TEXT("*.txt"), NULL, 4 | 2, TEXT("信息|*.txt||")); if (dlg.DoModal() == IDOK) { CString m_filename = dlg.GetPathName(); CString strInput; GetWindowText(strInput); CFile file(m_filename, CFile::modeCreate | CFile::modeWrite); #ifdef UNICODE WCHAR wFlag = 0xFEFF; file.Write(&wFlag, sizeof(WCHAR)); #endif //UNICODE file.Write(strInput, strInput.GetLength()); file.Close(); } setlocale(LC_CTYPE, old_local); free(old_local); } //删除字符 VOID CTraceServiceControl::OnDeleteString() { ReplaceSel(NULL, true); } //消息映射 /////////////////////////////////////////////////////////////////////////// //建立消息 INT CTraceServiceControl::OnCreate(LPCREATESTRUCT lpCreateStruct) { /*return __super::OnCreate(lpCreateStruct);*/ if (__super::OnCreate(lpCreateStruct) == -1) return -1; CTraceService::SetTraceService(this); return 0; } //右键消息 void CTraceServiceControl::OnRButtonDown(UINT nFlags, CPoint point) { CMenu menu; // 创建弹出菜单 if (menu.CreatePopupMenu()) { ClientToScreen(&point); CHARRANGE sel; GetSel(sel); int nTextLength = GetTextLength(); // 启用删除菜单 - 当有选中文本时可以删除 BOOL bCanDelete = (sel.cpMax != sel.cpMin); // 有选中文本才能删除 menu.AppendMenu(MF_STRING | ((sel.cpMax != sel.cpMin) ? 0 : (MF_DISABLED | MF_GRAYED)), IDM_MENU0, TEXT("复制(&C)\tCtrl+C")); menu.AppendMenu(MF_STRING | ((nTextLength > 0 && (sel.cpMax - sel.cpMin) < nTextLength) ? 0 : (MF_DISABLED | MF_GRAYED)), IDM_MENU1, TEXT("全选(&A)\tCtrl+A")); // 启用删除菜单(当有选中文本时) menu.AppendMenu(MF_STRING | (bCanDelete ? 0 : (MF_DISABLED | MF_GRAYED)), IDM_MENU2, TEXT("删除(&D)\tDel")); menu.AppendMenu(MF_STRING | ((nTextLength > 0) ? 0 : (MF_DISABLED | MF_GRAYED)), IDM_MENU3, TEXT("清除信息")); menu.AppendMenu(MF_SEPARATOR); menu.AppendMenu(MF_STRING | ((nTextLength > 0) ? 0 : (MF_DISABLED | MF_GRAYED)), IDM_MENU4, TEXT("保存信息")); // 显示菜单 menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this); } // 调用基类处理 __super::OnRButtonDown(nFlags, point); } //追踪消息 LRESULT CTraceServiceControl::OnTraceServiceMessage(WPARAM wParam, LPARAM lParam) { return 0; }
11-07
#include "docxtopdf.h" #include <QFile> #include <QTextStream> #include <QXmlStreamReader> #include <QPrinter> #include <QTextDocument> #include <QTextCursor> #include <QTextList> #include <QDebug> #include <quazip5/quazip.h> #include <quazip5/quazipfile.h> #include <QFileInfo> #include <QImageReader> #include <QPainter> #include <QPdfWriter> #include <QUuid> // XML namespaces const QString ns_w = "http://schemas.openxmlformats.org/wordprocessingml/2006/main"; const QString ns_r1 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships"; const QString ns_r2 = "http://schemas.openxmlformats.org/package/2006/relationships"; const QString ns_wp = "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"; const QString ns_a = "http://schemas.openxmlformats.org/drawingml/2006/main"; const QString ns_pic = "http://schemas.openxmlformats.org/drawingml/2006/picture"; DocxToPdfConverter::DocxToPdfConverter(QObject *parent) : QObject(parent) { } bool DocxToPdfConverter::convert(const QString &inputPath, const QString &outputPath) { // Reset state m_paragraphs.clear(); m_styles.clear(); m_imageRelations.clear(); m_extractedImages.clear(); m_numberingFormats.clear(); m_pageSettings.clear(); m_currentPageSettingIndex = 0; m_lastError.clear(); // Step 1: Extract and parse all necessary files from DOCX if (!extractContentFromDocx(inputPath)) { emit errorOccurred(m_lastError); return false; } // Step 2: Render to PDF if (!renderToPdf(outputPath)) { emit errorOccurred(m_lastError); return false; } emit conversionFinished(true); return true; } QString DocxToPdfConverter::lastError() const { return m_lastError; } bool DocxToPdfConverter::extractContentFromDocx(const QString &docxPath) { QuaZip zip(docxPath); if (!zip.open(QuaZip::mdUnzip)) { m_lastError = "Failed to open DOCX file as ZIP archive"; return false; } // Parse relationships first to find all images if (zip.setCurrentFile("word/_rels/document.xml.rels")) { QuaZipFile relsFile(&zip); if (relsFile.open(QIODevice::ReadOnly)) { parseRelationships(relsFile.readAll()); relsFile.close(); } } // Parse styles if (zip.setCurrentFile("word/styles.xml")) { QuaZipFile stylesFile(&zip); if (stylesFile.open(QIODevice::ReadOnly)) { parseStylesXml(stylesFile.readAll()); stylesFile.close(); } } // Parse numbering (lists) if (zip.setCurrentFile("word/numbering.xml")) { QuaZipFile numberingFile(&zip); if (numberingFile.open(QIODevice::ReadOnly)) { parseNumberingXml(numberingFile.readAll()); numberingFile.close(); } } // Parse main document content if (!zip.setCurrentFile("word/document.xml")) { m_lastError = "Could not find document.xml in DOCX archive"; zip.close(); return false; } QuaZipFile documentFile(&zip); if (!documentFile.open(QIODevice::ReadOnly)) { m_lastError = "Could not open document.xml in DOCX archive"; zip.close(); return false; } bool extractResult = extractImages(docxPath); // 提前执行 if (!extractResult) { zip.close(); return false; } bool result = parseDocumentXml(documentFile.readAll()); documentFile.close(); // // Extract images // if (result) { // result = extractImages(docxPath); // } zip.close(); return result; } bool DocxToPdfConverter::parseDocumentXml(const QByteArray &xmlData) { QXmlStreamReader xml(xmlData); Paragraph currentPara; TextRun currentRun; bool inParagraph = false; bool inRun = false; bool inDrawing = false; bool inSectionProperties = false; QString currentImageId; // Add default page settings (A4 with 1 inch margins) PageSettings defaultPage; defaultPage.size = QPageSize(QPageSize::A4).size(QPageSize::Point); defaultPage.margins = QMarginsF(72, 72, 72, 72); // 1 inch margins m_pageSettings.append(defaultPage); while (!xml.atEnd() && !xml.hasError()) { xml.readNext(); if (xml.isStartElement()) { if (xml.namespaceUri() == ns_w) { if (xml.name() == "p") { inParagraph = true; currentPara = Paragraph(); } else if (inParagraph && xml.name() == "r") { inRun = true; currentRun = TextRun(); } else if (inRun && xml.name() == "rPr") { // Run properties (formatting) while (xml.readNextStartElement()) { if (xml.namespaceUri() != ns_w) { xml.skipCurrentElement(); continue; } if (xml.name() == "sz") { int halfPoints = getXmlAttribute(xml.attributes(), "val", ns_w).toInt(); // 确保最小字号为6pt,最大为72pt qreal fontSize = qBound(6.0, halfPoints / 2.0, 72.0); currentRun.charFormat.setFontPointSize(fontSize); xml.skipCurrentElement(); } else if (xml.name() == "color") { QString color = getXmlAttribute(xml.attributes(), "val", ns_w); if (!color.isEmpty()) { //currentRun.charFormat.setForeground(QColor("#" + color)); if (color == "auto") { currentRun.charFormat.setForeground(Qt::black); // 默认黑色 } else { // 支持RGB颜色和主题颜色 QColor qcolor; if (color.startsWith("FF")) { // 处理ABGR格式 color = color.mid(2); qcolor = QColor("#" + color.mid(4,2) + color.mid(2,2) + color.left(2)); } else { qcolor = QColor("#" + color); } if (qcolor.isValid()) { currentRun.charFormat.setForeground(qcolor); } } } xml.skipCurrentElement(); } else if (xml.name() == "b") { currentRun.charFormat.setFontWeight(QFont::Bold); xml.skipCurrentElement(); } else if (xml.name() == "i") { currentRun.charFormat.setFontItalic(true); xml.skipCurrentElement(); } else if (xml.name() == "u") { QString underline = getXmlAttribute(xml.attributes(), "val", ns_w); if (underline != "none") { currentRun.charFormat.setFontUnderline(true); } xml.skipCurrentElement(); } else if (xml.name() == "rFonts") { QString font = getXmlAttribute(xml.attributes(), "ascii", ns_w); if (!font.isEmpty()) { currentRun.charFormat.setFontFamily(font); } xml.skipCurrentElement(); } else { xml.skipCurrentElement(); } } } else if (inRun && xml.name() == "t") { // Text content currentRun.text = xml.readElementText(); currentPara.runs.append(currentRun); } else if (inRun && xml.name() == "drawing") { // Start of drawing (image) inDrawing = true; currentImageId.clear(); // 确保每次处理新图片时清空ID } else if (inParagraph && xml.name() == "pPr") { // Paragraph properties while (xml.readNextStartElement()) { if (xml.namespaceUri() != ns_w) { xml.skipCurrentElement(); continue; } if (xml.name() == "pStyle") { QString styleId = getXmlAttribute(xml.attributes(), "val", ns_w); currentPara.styleName = styleId; if (m_styles.contains(styleId)) { currentPara.charFormat = m_styles[styleId]; } xml.skipCurrentElement(); } else if (xml.name() == "numPr") { currentPara.isList = true; xml.skipCurrentElement(); } else if (xml.name() == "pageBreakBefore") { currentPara.isPageBreak = true; xml.skipCurrentElement(); } else if (xml.name() == "spacing") { QString before = getXmlAttribute(xml.attributes(), "before", ns_w); QString after = getXmlAttribute(xml.attributes(), "after", ns_w); QString line = getXmlAttribute(xml.attributes(), "line", ns_w); QString lineRule = getXmlAttribute(xml.attributes(), "lineRule", ns_w); if (!before.isEmpty()) { currentPara.spacingBefore = twipsToPoints(before.toInt()); currentPara.blockFormat.setTopMargin(currentPara.spacingBefore); } if (!after.isEmpty()) { currentPara.spacingAfter = twipsToPoints(after.toInt()); currentPara.blockFormat.setBottomMargin(currentPara.spacingAfter); } if (!line.isEmpty()) { if (lineRule == "auto" || lineRule.isEmpty()) { // 自动行距 currentPara.lineHeight = line.toInt() / 240.0; // 240 = 12pt * 20twips/pt currentPara.blockFormat.setLineHeight(currentPara.lineHeight * 100, QTextBlockFormat::ProportionalHeight); } else if (lineRule == "exact") { // 固定行距 currentPara.lineHeight = twipsToPoints(line.toInt()); currentPara.blockFormat.setLineHeight(currentPara.lineHeight, QTextBlockFormat::FixedHeight); } else if (lineRule == "atLeast") { // 最小行距 currentPara.lineHeight = twipsToPoints(line.toInt()); currentPara.blockFormat.setLineHeight(currentPara.lineHeight, QTextBlockFormat::MinimumHeight); } } xml.skipCurrentElement(); } else if (xml.name() == "ind") { QString left = getXmlAttribute(xml.attributes(), "left", ns_w); QString right = getXmlAttribute(xml.attributes(), "right", ns_w); QString firstLine = getXmlAttribute(xml.attributes(), "firstLine", ns_w); if (!left.isEmpty()) currentPara.blockFormat.setLeftMargin(twipsToPoints(left.toInt())); if (!right.isEmpty()) currentPara.blockFormat.setRightMargin(twipsToPoints(right.toInt())); if (!firstLine.isEmpty()) { currentPara.blockFormat.setTextIndent(twipsToPoints(firstLine.toInt())); } xml.skipCurrentElement(); } else if (xml.name() == "jc") { QString align = getXmlAttribute(xml.attributes(), "val", ns_w); if (align == "center") { currentPara.blockFormat.setAlignment(Qt::AlignCenter); } else if (align == "right") { currentPara.blockFormat.setAlignment(Qt::AlignRight); } else if (align == "both") { currentPara.blockFormat.setAlignment(Qt::AlignJustify); } xml.skipCurrentElement(); } else if (xml.name() == "sectPr") { // Section properties (page settings) inSectionProperties = true; PageSettings pageSettings = m_pageSettings.last(); // Copy previous settings while (xml.readNextStartElement()) { if (xml.namespaceUri() != ns_w) { xml.skipCurrentElement(); continue; } if (xml.name() == "pgSz") { // Page size QString width = getXmlAttribute(xml.attributes(), "w", ns_w); QString height = getXmlAttribute(xml.attributes(), "h", ns_w); if (!width.isEmpty() && !height.isEmpty()) { pageSettings.size = QSizeF(twipsToPoints(width.toInt()), twipsToPoints(height.toInt())); } xml.skipCurrentElement(); } else if (xml.name() == "pgMar") { // Page margins QString top = getXmlAttribute(xml.attributes(), "top", ns_w); QString right = getXmlAttribute(xml.attributes(), "right", ns_w); QString bottom = getXmlAttribute(xml.attributes(), "bottom", ns_w); QString left = getXmlAttribute(xml.attributes(), "left", ns_w); if (!top.isEmpty()) pageSettings.margins.setTop(twipsToPoints(top.toInt())); if (!right.isEmpty()) pageSettings.margins.setRight(twipsToPoints(right.toInt())); if (!bottom.isEmpty()) pageSettings.margins.setBottom(twipsToPoints(bottom.toInt())); if (!left.isEmpty()) pageSettings.margins.setLeft(twipsToPoints(left.toInt())); xml.skipCurrentElement(); } else if (xml.name() == "type") { // Section break type QString type = getXmlAttribute(xml.attributes(), "val", ns_w); if (type == "nextPage") { currentPara.isSectionBreak = true; } xml.skipCurrentElement(); } else { xml.skipCurrentElement(); } } m_pageSettings.append(pageSettings); inSectionProperties = false; } else { xml.skipCurrentElement(); } } } } else if (xml.namespaceUri() == ns_a && xml.name() == "blip") { currentImageId = getXmlAttribute(xml.attributes(), "embed", ns_r2); if (!currentImageId.isEmpty()) { currentRun = TextRun(); // 重置运行 currentRun.isImage = true; currentRun.imageName = QString("image_%1").arg(currentImageId); } xml.skipCurrentElement(); } // else if (inDrawing && xml.namespaceUri() == ns_a && xml.name() == "blip") { // // Image reference // currentImageId = getXmlAttribute(xml.attributes(), "embed", ns_r2); // xml.skipCurrentElement(); // } else if (inDrawing && xml.namespaceUri() == ns_wp && xml.name() == "inline") { qreal widthEmu = 0, heightEmu = 0; while (xml.readNextStartElement()) { if (xml.namespaceUri() == ns_wp && xml.name() == "extent") { widthEmu = getXmlAttribute(xml.attributes(), "cx", ns_wp).toDouble(); heightEmu = getXmlAttribute(xml.attributes(), "cy", ns_wp).toDouble(); xml.skipCurrentElement(); } else { xml.skipCurrentElement(); } } // EMU 转磅(1英寸=914400 EMU=72磅) if (widthEmu > 0 && heightEmu > 0) { currentRun.imageSize = QSizeF(widthEmu / 12700, heightEmu / 12700); qDebug() << "Parsed image size from EMU:" << currentRun.imageSize << "pt"; } } } else if (xml.isEndElement()) { if (xml.namespaceUri() == ns_w) { if (xml.name() == "p" && inParagraph) { // 如果有图片ID但未处理,尝试绑定图片 if (!currentImageId.isEmpty() && m_extractedImages.contains(currentImageId)) { currentRun.isImage = true; currentRun.image = m_extractedImages[currentImageId]; currentPara.runs.append(currentRun); } // 保存段落 if (!currentPara.runs.isEmpty() || currentPara.isPageBreak) { m_paragraphs.append(currentPara); } inParagraph = false; } // if (xml.name() == "p" && inParagraph) { // // End of paragraph // if (!currentPara.runs.isEmpty() || currentPara.isPageBreak || currentPara.isSectionBreak) { // m_paragraphs.append(currentPara); // } // inParagraph = false; // } else if (xml.name() == "r" && inRun) { if (currentRun.isImage && !currentImageId.isEmpty() && m_extractedImages.contains(currentImageId)) { currentRun.image = m_extractedImages[currentImageId]; currentPara.runs.append(currentRun); qDebug() << "Added image run:" << currentImageId << "Size:" << currentRun.image.size(); } inRun = false; } } else if (xml.namespaceUri() == ns_w && xml.name() == "drawing") { // End of drawing (image) inDrawing = false; if (!currentImageId.isEmpty() && m_extractedImages.contains(currentImageId)) { currentRun.isImage = true; currentRun.image = m_extractedImages[currentImageId]; currentRun.imageName = QString("image_%1").arg(currentImageId); currentRun.imageSize = QSizeF( currentRun.image.width() / currentRun.image.dotsPerMeterX() * 72.0, currentRun.image.height() / currentRun.image.dotsPerMeterY() * 72.0 ); currentPara.runs.append(currentRun); } currentImageId.clear(); } } } if (xml.hasError()) { m_lastError = QString("XML parsing error: %1").arg(xml.errorString()); return false; } qDebug() << "=== Image Debug Info ==="; qDebug() << "Extracted images count:" << m_extractedImages.size(); qDebug() << "Image relationships:" << m_imageRelations; qDebug() << "Total paragraphs:" << m_paragraphs.size(); for (int i = 0; i < m_paragraphs.size(); ++i) { const Paragraph& para = m_paragraphs[i]; qDebug() << "Paragraph" << i << "runs:" << para.runs.size(); for (int j = 0; j < para.runs.size(); ++j) { if (para.runs[j].isImage) { qDebug() << " Run" << j << "is IMAGE, ID:" << para.runs[j].imageName; } } } return true; } bool DocxToPdfConverter::parseStylesXml(const QByteArray &xmlData) { QXmlStreamReader xml(xmlData); QString currentStyleId; QTextCharFormat currentFormat; while (!xml.atEnd() && !xml.hasError()) { xml.readNext(); if (xml.isStartElement() && xml.namespaceUri() == ns_w) { if (xml.name() == "style") { currentStyleId = getXmlAttribute(xml.attributes(), "styleId", ns_w); QString type = getXmlAttribute(xml.attributes(), "type", ns_w); if (type != "character" && type != "paragraph") { currentStyleId.clear(); } } else if (!currentStyleId.isEmpty() && xml.name() == "rPr") { while (xml.readNextStartElement()) { if (xml.namespaceUri() != ns_w) { xml.skipCurrentElement(); continue; } if (xml.name() == "sz") { int halfPoints = getXmlAttribute(xml.attributes(), "val", ns_w).toInt(); currentFormat.setFontPointSize(halfPoints / 2.0); xml.skipCurrentElement(); } else if (xml.name() == "color") { QString color = getXmlAttribute(xml.attributes(), "val", ns_w); if (!color.isEmpty()) { currentFormat.setForeground(QColor("#" + color)); } xml.skipCurrentElement(); } else if (xml.name() == "b") { currentFormat.setFontWeight(QFont::Bold); xml.skipCurrentElement(); } else if (xml.name() == "i") { currentFormat.setFontItalic(true); xml.skipCurrentElement(); } else if (xml.name() == "rFonts") { QString font = getXmlAttribute(xml.attributes(), "ascii", ns_w); if (!font.isEmpty()) { currentFormat.setFontFamily(font); } xml.skipCurrentElement(); } else { xml.skipCurrentElement(); } } } } else if (xml.isEndElement() && xml.namespaceUri() == ns_w) { if (xml.name() == "style" && !currentStyleId.isEmpty()) { m_styles[currentStyleId] = currentFormat; currentStyleId.clear(); currentFormat = QTextCharFormat(); } } } if (xml.hasError()) { m_lastError = QString("Styles XML parsing error: %1").arg(xml.errorString()); return false; } return true; } bool DocxToPdfConverter::parseNumberingXml(const QByteArray &xmlData) { QXmlStreamReader xml(xmlData); int currentNumId = -1; while (!xml.atEnd() && !xml.hasError()) { xml.readNext(); if (xml.isStartElement() && xml.namespaceUri() == ns_w) { if (xml.name() == "num") { currentNumId = getXmlAttribute(xml.attributes(), "numId", ns_w).toInt(); } else if (currentNumId != -1 && xml.name() == "numFmt") { QString format = getXmlAttribute(xml.attributes(), "val", ns_w); m_numberingFormats[currentNumId] = format; } } else if (xml.isEndElement() && xml.namespaceUri() == ns_w) { if (xml.name() == "num") { currentNumId = -1; } } } if (xml.hasError()) { m_lastError = QString("Numbering XML parsing error: %1").arg(xml.errorString()); return false; } return true; } bool DocxToPdfConverter::parseRelationships(const QByteArray &xmlData) { QXmlStreamReader xml(xmlData); const QString relNs = "http://schemas.openxmlformats.org/package/2006/relationships"; while (!xml.atEnd()) { xml.readNext(); if (xml.isStartElement() && xml.name() == "Relationship") { // 直接获取属性值(不依赖命名空间) QXmlStreamAttributes attrs = xml.attributes(); QString id = attrs.value("Id").toString(); QString target = attrs.value("Target").toString(); QString type = attrs.value("Type").toString(); // 检查是否是图片类型 if (type.contains("image") || type.endsWith("png", Qt::CaseInsensitive) || type.endsWith("jpg", Qt::CaseInsensitive) || type.endsWith("jpeg", Qt::CaseInsensitive)) { // 标准化路径 QString fullPath = "word/" + target; fullPath = fullPath.replace("\\", "/"); m_imageRelations[id] = fullPath; qDebug() << "Found image relationship: ID =" << id << "Path =" << fullPath << "Type =" << type; } } } if (xml.hasError()) { m_lastError = "Relationships XML error: " + xml.errorString(); return false; } return true; } bool DocxToPdfConverter::extractImages(const QString &docxPath) { QuaZip zip(docxPath); if (!zip.open(QuaZip::mdUnzip)) { m_lastError = "Failed to open DOCX file"; return false; } for (const auto &rel : m_imageRelations.keys()) { QString imagePath = m_imageRelations[rel]; if (!zip.setCurrentFile(imagePath)) { qDebug() << "Image not found:" << imagePath; continue; } QuaZipFile imageFile(&zip); if (!imageFile.open(QIODevice::ReadOnly)) { qDebug() << "Failed to open image:" << imagePath; continue; } QByteArray imageData = imageFile.readAll(); imageFile.close(); QImage image; if (image.loadFromData(imageData)) { // // 转换为不透明格式 // if (image.format() == QImage::Format_ARGB32) { // image = image.convertToFormat(QImage::Format_RGB32); // } // m_extractedImages[rel] = image; qDebug() << "Successfully loaded image:" << imagePath << "Size:" << image.size() << "Format:" << image.format(); // 确保图片有有效的DPI信息 if (image.dotsPerMeterX() <= 0 || image.dotsPerMeterY() <= 0) { image.setDotsPerMeterX(2835); // 72 DPI image.setDotsPerMeterY(2835); // 72 DPI } m_extractedImages[rel] = image; } else { qDebug() << "Failed to load image data:" << imagePath << "Data size:" << imageData.size(); // 创建占位图 QImage placeholder(300, 100, QImage::Format_RGB32); placeholder.fill(Qt::white); QPainter painter(&placeholder); painter.setPen(Qt::red); painter.drawText(10, 50, "Image Load Error"); painter.end(); m_extractedImages[rel] = placeholder; } } qDebug() << "Extracted images:" << m_extractedImages.keys(); zip.close(); return true; } bool DocxToPdfConverter::renderToPdf(const QString &outputPath) { QPrinter printer(QPrinter::HighResolution); printer.setOutputFormat(QPrinter::PdfFormat); printer.setOutputFileName(outputPath); applyCurrentPageSettings(printer); QTextDocument document; document.setPageSize(printer.pageRect(QPrinter::Point).size()); document.setDocumentMargin(0); // 使用边距控制 // 设置默认字体和文本选项 QFont defaultFont("Times New Roman", 12); document.setDefaultFont(defaultFont); QTextOption textOption; textOption.setAlignment(Qt::AlignLeft); textOption.setWrapMode(QTextOption::WordWrap); document.setDefaultTextOption(textOption); QTextCursor cursor(&document); for (const Paragraph &para : m_paragraphs) { // 处理分页和分段 if (para.isSectionBreak) { m_currentPageSettingIndex = qMin(m_currentPageSettingIndex + 1, m_pageSettings.size() - 1); applyCurrentPageSettings(printer); document.setPageSize(printer.pageRect(QPrinter::Point).size()); QTextBlockFormat breakFormat; breakFormat.setPageBreakPolicy(QTextFormat::PageBreak_AlwaysBefore); cursor.insertBlock(breakFormat); continue; } if (para.isPageBreak) { QTextBlockFormat breakFormat; breakFormat.setPageBreakPolicy(QTextFormat::PageBreak_AlwaysBefore); cursor.insertBlock(breakFormat); continue; } // 设置段落格式 QTextBlockFormat blockFormat = para.blockFormat; // 处理列表 if (para.isList) { QTextListFormat listFormat; listFormat.setIndent(para.listLevel + 1); listFormat.setStyle(QTextListFormat::ListDecimal); cursor.insertList(listFormat); } else { cursor.insertBlock(blockFormat); } // 添加文本运行 for (const TextRun &run : para.runs) { qDebug() << "run.isImage:" << run.isImage; if (run.isImage && !run.image.isNull()) { qDebug() << "存在图片"; // 1. 确保图片格式兼容PDF(ARGB32可能有问题,转换为RGB32) QImage compatibleImage = run.image; if (compatibleImage.format() == QImage::Format_ARGB32) { compatibleImage = compatibleImage.convertToFormat(QImage::Format_RGB32); } // 2. 直接使用内存资源(不依赖文件路径) QString resourceName = "img_" + QUuid::createUuid().toString(QUuid::WithoutBraces); document.addResource(QTextDocument::ImageResource, QUrl(resourceName), compatibleImage); // 3. 计算并设置图片尺寸(单位:磅) qreal widthPt = run.imageSize.width() > 0 ? run.imageSize.width() : 200; // 默认200磅 qreal heightPt = run.imageSize.height() > 0 ? run.imageSize.height() : widthPt * compatibleImage.height() / compatibleImage.width(); // 4. 限制图片不超过页面宽度 qreal maxWidth; if (m_currentPageSettingIndex < m_pageSettings.size()) { // 使用自定义的页面设置 const PageSettings &settings = m_pageSettings[m_currentPageSettingIndex]; maxWidth = printer.pageRect(QPrinter::Point).width() - settings.margins.left() - settings.margins.right(); } else { // 回退到打印机默认设置(单位:磅) QPageLayout layout = printer.pageLayout(); maxWidth = printer.pageRect(QPrinter::Point).width() - layout.margins().left() - layout.margins().right(); } if (widthPt > maxWidth) { heightPt = heightPt * (maxWidth / widthPt); widthPt = maxWidth; } // 5. 插入图片 QTextImageFormat imageFormat; imageFormat.setName(resourceName); imageFormat.setWidth(widthPt); imageFormat.setHeight(heightPt); cursor.insertImage(imageFormat); qDebug() << "Inserted image:" << resourceName << "Size (pt):" << widthPt << "x" << heightPt << "Original size:" << compatibleImage.size(); qDebug() << "Document image resources:" << document.resource(QTextDocument::ImageResource, QUrl()).isValid(); // 强制立即渲染(测试用) document.print(&printer); if (printer.printerState() == QPrinter::Error) { qDebug() << "PDF generation failed:"; } else { qDebug() << "PDF generated successfully at" << outputPath; } } else { // 合并格式并确保字体属性正确 QTextCharFormat format = para.charFormat; format.merge(run.charFormat); // 确保重要属性不被覆盖 if (run.charFormat.hasProperty(QTextFormat::FontFamily)) { format.setFontFamily(run.charFormat.fontFamily()); } if (run.charFormat.hasProperty(QTextFormat::FontPointSize)) { format.setFontPointSize(run.charFormat.fontPointSize()); } if (run.charFormat.hasProperty(QTextFormat::FontWeight)) { format.setFontWeight(run.charFormat.fontWeight()); } if (run.charFormat.hasProperty(QTextFormat::FontItalic)) { format.setFontItalic(run.charFormat.fontItalic()); } if (run.charFormat.hasProperty(QTextFormat::TextUnderlineStyle)) { format.setFontUnderline(run.charFormat.fontUnderline()); } if (run.charFormat.hasProperty(QTextFormat::ForegroundBrush)) { format.setForeground(run.charFormat.foreground()); } cursor.insertText(run.text, format); } } } // 渲染PDF document.print(&printer); if (printer.printerState() == QPrinter::Error) { //m_lastError = "Failed to generate PDF: " + printer.errorString(); return false; } return true; } QString DocxToPdfConverter::getXmlAttribute(const QXmlStreamAttributes &attrs, const QString &name, const QString &ns) { // 首先尝试使用指定命名空间 if (!ns.isEmpty()) { QString value = attrs.value(ns, name).toString(); if (!value.isEmpty()) return value; } // 然后尝试不使用命名空间 return attrs.value(name).toString(); } void DocxToPdfConverter::applyCurrentPageSettings(QPrinter &printer) { if (m_currentPageSettingIndex < m_pageSettings.size()) { const PageSettings &settings = m_pageSettings[m_currentPageSettingIndex]; // Find closest QPageSize QPageSize pageSize(settings.size, QPageSize::Point, "", QPageSize::ExactMatch); if (!pageSize.isValid()) { pageSize = QPageSize(settings.size, QPageSize::Point); } printer.setPageSize(pageSize); printer.setPageMargins(settings.margins, QPageLayout::Point); } } 当前代码的打印存在如下问题:cursor, ========== cshape: 0 cursor, size from XGetDefault: 24 cursor, size from ptrXcursorLibraryGetDefaultSize: 24 Found image relationship: ID = "rId6" Path = "word/media/sign20250805.102526_photo.png" Type = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Successfully loaded image: "word/media/sign20250805.102526_photo.png" Size: QSize(1232, 588) Format: QImage::Format_ARGB32 Extracted images: ("rId6") === Image Debug Info === Extracted images count: 1 Image relationships: QMap(("rId6", "word/media/sign20250805.102526_photo.png")) Total paragraphs: 25 Paragraph 0 runs: 7 Paragraph 1 runs: 3 Paragraph 2 runs: 3 Paragraph 3 runs: 15 Paragraph 4 runs: 5 Paragraph 5 runs: 10 Paragraph 6 runs: 8 Paragraph 7 runs: 6 Paragraph 8 runs: 8 Paragraph 9 runs: 4 Paragraph 10 runs: 5 Paragraph 11 runs: 4 Paragraph 12 runs: 4 Paragraph 13 runs: 2 Paragraph 14 runs: 2 Paragraph 15 runs: 2 Paragraph 16 runs: 2 Paragraph 17 runs: 1 Paragraph 18 runs: 1 Paragraph 19 runs: 24 Paragraph 20 runs: 1 Paragraph 21 runs: 7 Paragraph 22 runs: 2 Paragraph 23 runs: 1 Paragraph 24 runs: 12 run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false run.isImage: false,还是依然转换之后不存在签名图片,如何解决
08-07
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值