Diff of /src/Exporters.cxx [3fdc43] .. [fc4fc0]  Maximize  Restore

Switch to side-by-side view

--- a/src/Exporters.cxx
+++ b/src/Exporters.cxx
@@ -17,6 +17,7 @@
 #include <vector>
 #include <set>
 #include <map>
+#include <sstream>
 
 #if defined(__unix__)
 
@@ -73,10 +74,8 @@
 
 #define RTF_HEADEROPEN "{\\rtf1\\ansi\\deff0\\deftab720"
 #define RTF_FONTDEFOPEN "{\\fonttbl"
-#define RTF_FONTDEF "{\\f%d\\fnil\\fcharset%u %s;}"
 #define RTF_FONTDEFCLOSE "}"
 #define RTF_COLORDEFOPEN "{\\colortbl"
-#define RTF_COLORDEF "\\red%d\\green%d\\blue%d;"
 #define RTF_COLORDEFCLOSE "}"
 #define RTF_HEADERCLOSE "\n"
 #define RTF_BODYOPEN ""
@@ -136,7 +135,7 @@
 	strcpy(last, current);
 }
 
-void SciTEBase::SaveToRTF(FilePath saveName, int start, int end) {
+void SciTEBase::SaveToStreamRTF(std::ostream &os, int start, int end) {
 	int lengthDoc = LengthDocument();
 	if (end < 0)
 		end = lengthDoc;
@@ -177,144 +176,151 @@
 	if (tabSize == 0)
 		tabSize = 4;
 
+	char styles[STYLE_MAX + 1][MAX_STYLEDEF];
+	char fonts[STYLE_MAX + 1][MAX_FONTDEF];
+	char colors[STYLE_MAX + 1][MAX_COLORDEF];
+	char lastStyle[MAX_STYLEDEF], deltaStyle[MAX_STYLEDEF];
+	int fontCount = 1, colorCount = 2, i;
+	os << RTF_HEADEROPEN << RTF_FONTDEFOPEN;
+	StringCopy(fonts[0], defaultStyle.font.c_str());
+	os << "{\\f" << 0 << "\\fnil\\fcharset" << characterset << " " << defaultStyle.font.c_str() << ";}";
+	StringCopy(colors[0], defaultStyle.fore.c_str());
+	StringCopy(colors[1], defaultStyle.back.c_str());
+
+	for (int istyle = 0; istyle <= STYLE_MAX; istyle++) {
+		sprintf(key, "style.*.%0d", istyle);
+		char *valdef = StringDup(props.GetExpanded(key).c_str());
+		sprintf(key, "style.%s.%0d", language.c_str(), istyle);
+		char *val = StringDup(props.GetExpanded(key).c_str());
+
+		StyleDefinition sd(valdef);
+		sd.ParseStyleDefinition(val);
+
+		if (sd.specified != StyleDefinition::sdNone) {
+			if (wysiwyg && sd.font.length()) {
+				for (i = 0; i < fontCount; i++)
+					if (EqualCaseInsensitive(sd.font.c_str(), fonts[i]))
+						break;
+				if (i >= fontCount) {
+					StringCopy(fonts[fontCount++], sd.font.c_str());
+					os << "{\\f" << i << "\\fnil\\fcharset" << characterset << " " << sd.font.c_str() << ";}";
+				}
+				sprintf(lastStyle, RTF_SETFONTFACE "%d", i);
+			} else {
+				strcpy(lastStyle, RTF_SETFONTFACE "0");
+			}
+
+			sprintf(lastStyle + strlen(lastStyle), RTF_SETFONTSIZE "%d",
+				wysiwyg && sd.size ? sd.size << 1 : defaultStyle.size);
+
+			if (sd.specified & StyleDefinition::sdFore) {
+				for (i = 0; i < colorCount; i++)
+					if (EqualCaseInsensitive(sd.fore.c_str(), colors[i]))
+						break;
+				if (i >= colorCount)
+					StringCopy(colors[colorCount++], sd.fore.c_str());
+				sprintf(lastStyle + strlen(lastStyle), RTF_SETCOLOR "%d", i);
+			} else {
+				strcat(lastStyle, RTF_SETCOLOR "0");	// Default fore
+			}
+
+			// PL: highlights doesn't seems to follow a distinct table, at least with WordPad and Word 97
+			// Perhaps it is different for Word 6?
+//				sprintf(lastStyle + strlen(lastStyle), RTF_SETBACKGROUND "%d",
+//				        sd.back.length() ? GetRTFHighlight(sd.back.c_str()) : 0);
+			if (sd.specified & StyleDefinition::sdBack) {
+				for (i = 0; i < colorCount; i++)
+					if (EqualCaseInsensitive(sd.back.c_str(), colors[i]))
+						break;
+				if (i >= colorCount)
+					StringCopy(colors[colorCount++], sd.back.c_str());
+				sprintf(lastStyle + strlen(lastStyle), RTF_SETBACKGROUND "%d", i);
+			} else {
+				strcat(lastStyle, RTF_SETBACKGROUND "1");	// Default back
+			}
+			if (sd.specified & StyleDefinition::sdWeight) {
+				strcat(lastStyle, sd.IsBold() ? RTF_BOLD_ON : RTF_BOLD_OFF);
+			} else {
+				strcat(lastStyle, defaultStyle.IsBold() ? RTF_BOLD_ON : RTF_BOLD_OFF);
+			}
+			if (sd.specified & StyleDefinition::sdItalics) {
+				strcat(lastStyle, sd.italics ? RTF_ITALIC_ON : RTF_ITALIC_OFF);
+			} else {
+				strcat(lastStyle, defaultStyle.italics ? RTF_ITALIC_ON : RTF_ITALIC_OFF);
+			}
+			StringCopy(styles[istyle], lastStyle);
+		} else {
+			sprintf(styles[istyle], RTF_SETFONTFACE "0" RTF_SETFONTSIZE "%d"
+				RTF_SETCOLOR "0" RTF_SETBACKGROUND "1"
+				RTF_BOLD_OFF RTF_ITALIC_OFF, defaultStyle.size);
+		}
+		delete []val;
+		delete []valdef;
+	}
+	os << RTF_FONTDEFCLOSE RTF_COLORDEFOPEN;
+	for (i = 0; i < colorCount; i++) {
+		os << "\\red" << IntFromHexByte(colors[i] + 1) << "\\green" << IntFromHexByte(colors[i] + 3) <<
+			"\\blue" << IntFromHexByte(colors[i] + 5) << ";";
+	}
+	os << RTF_COLORDEFCLOSE RTF_HEADERCLOSE RTF_BODYOPEN RTF_SETFONTFACE "0"
+		RTF_SETFONTSIZE << defaultStyle.size << RTF_SETCOLOR "0 ";
+	sprintf(lastStyle, RTF_SETFONTFACE "0" RTF_SETFONTSIZE "%d"
+		RTF_SETCOLOR "0" RTF_SETBACKGROUND "1"
+		RTF_BOLD_OFF RTF_ITALIC_OFF, defaultStyle.size);
+	bool prevCR = false;
+	int styleCurrent = -1;
+	TextReader acc(wEditor);
+	int column = 0;
+	for (i = start; i < end; i++) {
+		char ch = acc[i];
+		int style = acc.StyleAt(i);
+		if (style > STYLE_MAX)
+			style = 0;
+		if (style != styleCurrent) {
+			GetRTFStyleChange(deltaStyle, lastStyle, styles[style]);
+			if (*deltaStyle)
+				os << deltaStyle;
+			styleCurrent = style;
+		}
+		if (ch == '{')
+			os << "\\{";
+		else if (ch == '}')
+			os << "\\}";
+		else if (ch == '\\')
+			os << "\\\\";
+		else if (ch == '\t') {
+			if (tabs) {
+				os << RTF_TAB;
+			} else {
+				int ts = tabSize - (column % tabSize);
+				for (int itab = 0; itab < ts; itab++) {
+					os << ' ';
+				}
+				column += ts - 1;
+			}
+		} else if (ch == '\n') {
+			if (!prevCR) {
+				os << RTF_EOLN;
+				column = -1;
+			}
+		} else if (ch == '\r') {
+			os << RTF_EOLN;
+			column = -1;
+		} else
+			os << ch;
+		column++;
+		prevCR = ch == '\r';
+	}
+	os << RTF_BODYCLOSE;
+}
+
+void SciTEBase::SaveToRTF(FilePath saveName, int start, int end) {
 	FILE *fp = saveName.Open(GUI_TEXT("wt"));
 	if (fp) {
-		char styles[STYLE_MAX + 1][MAX_STYLEDEF];
-		char fonts[STYLE_MAX + 1][MAX_FONTDEF];
-		char colors[STYLE_MAX + 1][MAX_COLORDEF];
-		char lastStyle[MAX_STYLEDEF], deltaStyle[MAX_STYLEDEF];
-		int fontCount = 1, colorCount = 2, i;
-		fputs(RTF_HEADEROPEN RTF_FONTDEFOPEN, fp);
-		StringCopy(fonts[0], defaultStyle.font.c_str());
-		fprintf(fp, RTF_FONTDEF, 0, characterset, defaultStyle.font.c_str());
-		StringCopy(colors[0], defaultStyle.fore.c_str());
-		StringCopy(colors[1], defaultStyle.back.c_str());
-
-		for (int istyle = 0; istyle <= STYLE_MAX; istyle++) {
-			sprintf(key, "style.*.%0d", istyle);
-			char *valdef = StringDup(props.GetExpanded(key).c_str());
-			sprintf(key, "style.%s.%0d", language.c_str(), istyle);
-			char *val = StringDup(props.GetExpanded(key).c_str());
-
-			StyleDefinition sd(valdef);
-			sd.ParseStyleDefinition(val);
-
-			if (sd.specified != StyleDefinition::sdNone) {
-				if (wysiwyg && sd.font.length()) {
-					for (i = 0; i < fontCount; i++)
-						if (EqualCaseInsensitive(sd.font.c_str(), fonts[i]))
-							break;
-					if (i >= fontCount) {
-						StringCopy(fonts[fontCount++], sd.font.c_str());
-						fprintf(fp, RTF_FONTDEF, i, characterset, sd.font.c_str());
-					}
-					sprintf(lastStyle, RTF_SETFONTFACE "%d", i);
-				} else {
-					strcpy(lastStyle, RTF_SETFONTFACE "0");
-				}
-
-				sprintf(lastStyle + strlen(lastStyle), RTF_SETFONTSIZE "%d",
-				        wysiwyg && sd.size ? sd.size << 1 : defaultStyle.size);
-
-				if (sd.specified & StyleDefinition::sdFore) {
-					for (i = 0; i < colorCount; i++)
-						if (EqualCaseInsensitive(sd.fore.c_str(), colors[i]))
-							break;
-					if (i >= colorCount)
-						StringCopy(colors[colorCount++], sd.fore.c_str());
-					sprintf(lastStyle + strlen(lastStyle), RTF_SETCOLOR "%d", i);
-				} else {
-					strcat(lastStyle, RTF_SETCOLOR "0");	// Default fore
-				}
-
-				// PL: highlights doesn't seems to follow a distinct table, at least with WordPad and Word 97
-				// Perhaps it is different for Word 6?
-//				sprintf(lastStyle + strlen(lastStyle), RTF_SETBACKGROUND "%d",
-//				        sd.back.length() ? GetRTFHighlight(sd.back.c_str()) : 0);
-				if (sd.specified & StyleDefinition::sdBack) {
-					for (i = 0; i < colorCount; i++)
-						if (EqualCaseInsensitive(sd.back.c_str(), colors[i]))
-							break;
-					if (i >= colorCount)
-						StringCopy(colors[colorCount++], sd.back.c_str());
-					sprintf(lastStyle + strlen(lastStyle), RTF_SETBACKGROUND "%d", i);
-				} else {
-					strcat(lastStyle, RTF_SETBACKGROUND "1");	// Default back
-				}
-				if (sd.specified & StyleDefinition::sdWeight) {
-					strcat(lastStyle, sd.IsBold() ? RTF_BOLD_ON : RTF_BOLD_OFF);
-				} else {
-					strcat(lastStyle, defaultStyle.IsBold() ? RTF_BOLD_ON : RTF_BOLD_OFF);
-				}
-				if (sd.specified & StyleDefinition::sdItalics) {
-					strcat(lastStyle, sd.italics ? RTF_ITALIC_ON : RTF_ITALIC_OFF);
-				} else {
-					strcat(lastStyle, defaultStyle.italics ? RTF_ITALIC_ON : RTF_ITALIC_OFF);
-				}
-				StringCopy(styles[istyle], lastStyle);
-			} else {
-				sprintf(styles[istyle], RTF_SETFONTFACE "0" RTF_SETFONTSIZE "%d"
-				        RTF_SETCOLOR "0" RTF_SETBACKGROUND "1"
-				        RTF_BOLD_OFF RTF_ITALIC_OFF, defaultStyle.size);
-			}
-			delete []val;
-			delete []valdef;
-		}
-		fputs(RTF_FONTDEFCLOSE RTF_COLORDEFOPEN, fp);
-		for (i = 0; i < colorCount; i++) {
-			fprintf(fp, RTF_COLORDEF, IntFromHexByte(colors[i] + 1),
-			        IntFromHexByte(colors[i] + 3), IntFromHexByte(colors[i] + 5));
-		}
-		fprintf(fp, RTF_COLORDEFCLOSE RTF_HEADERCLOSE RTF_BODYOPEN RTF_SETFONTFACE "0"
-		        RTF_SETFONTSIZE "%d" RTF_SETCOLOR "0 ", defaultStyle.size);
-		sprintf(lastStyle, RTF_SETFONTFACE "0" RTF_SETFONTSIZE "%d"
-		        RTF_SETCOLOR "0" RTF_SETBACKGROUND "1"
-		        RTF_BOLD_OFF RTF_ITALIC_OFF, defaultStyle.size);
-		bool prevCR = false;
-		int styleCurrent = -1;
-		TextReader acc(wEditor);
-		int column = 0;
-		for (i = start; i < end; i++) {
-			char ch = acc[i];
-			int style = acc.StyleAt(i);
-			if (style > STYLE_MAX)
-				style = 0;
-			if (style != styleCurrent) {
-				GetRTFStyleChange(deltaStyle, lastStyle, styles[style]);
-				if (*deltaStyle)
-					fputs(deltaStyle, fp);
-				styleCurrent = style;
-			}
-			if (ch == '{')
-				fputs("\\{", fp);
-			else if (ch == '}')
-				fputs("\\}", fp);
-			else if (ch == '\\')
-				fputs("\\\\", fp);
-			else if (ch == '\t') {
-				if (tabs) {
-					fputs(RTF_TAB, fp);
-				} else {
-					int ts = tabSize - (column % tabSize);
-					for (int itab = 0; itab < ts; itab++) {
-						fputc(' ', fp);
-					}
-					column += ts - 1;
-				}
-			} else if (ch == '\n') {
-				if (!prevCR) {
-					fputs(RTF_EOLN, fp);
-					column = -1;
-				}
-			} else if (ch == '\r') {
-				fputs(RTF_EOLN, fp);
-				column = -1;
-			} else
-				fputc(ch, fp);
-			column++;
-			prevCR = ch == '\r';
-		}
-		fputs(RTF_BODYCLOSE, fp);
+		std::ostringstream oss;
+		SaveToStreamRTF(oss, start, end);
+		std::string rtf = oss.str();
+		fwrite(rtf.c_str(), 1, rtf.length(), fp);
 		fclose(fp);
 	} else {
 		GUI::gui_string msg = LocaliseMessage("Could not save file '^0'.", filePath.AsInternal());