Skip to content

Commit

Permalink
Merge pull request #41 from dotnet-campus/t/lindexi/Update
Browse files Browse the repository at this point in the history
同步11月版本
  • Loading branch information
ZhengDaoWang authored Dec 13, 2023
2 parents d3acfb3 + 5542357 commit 6602f56
Show file tree
Hide file tree
Showing 9 changed files with 360 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -697,8 +697,10 @@ internal void AddContentType(CompatiblePackage.PackUriHelper.ValidatedPartUri pa
//partUri provided. Override takes precedence over the default entries
if (_overrideDictionary != null)
{
if (_overrideDictionary.ContainsKey(partUri))
return _overrideDictionary[partUri];
if (_overrideDictionary.TryGetValue(partUri, out var result))
{
return result;
}
}

//Step 2: Check if there is a default entry corresponding to the
Expand Down Expand Up @@ -789,9 +791,11 @@ private void EnsureOverrideDictionary()
{
// The part Uris are stored in the Override Dictionary in their original form , but they are compared
// in a normalized manner using the PartUriComparer
if (_overrideDictionary == null)
_overrideDictionary =
new Dictionary<CompatiblePackage.PackUriHelper.ValidatedPartUri, CompatiblePackage.ContentType>(OverrideDictionaryInitialSize);
_overrideDictionary ??= new Dictionary<CompatiblePackage.PackUriHelper.ValidatedPartUri, CompatiblePackage.ContentType>(
OverrideDictionaryInitialSize,
// 这里需要忽略字符串的大小写
// 修复 https://github.com/dotnet/Open-XML-SDK/issues/1355
new ValidatedPartUriIgnoreCaseEqualityComparer());
}

private void ParseContentTypesFile(
Expand Down Expand Up @@ -1097,5 +1101,19 @@ private void ThrowIfXmlAttributeMissing(string attributeName, string? attributeV
private const string PartNameAttributeName = "PartName";
private const string TemporaryPartNameWithoutExtension = "/tempfiles/sample.";
}

class ValidatedPartUriIgnoreCaseEqualityComparer : IEqualityComparer<
CompatiblePackage.PackUriHelper.ValidatedPartUri>
{
public bool Equals(PackUriHelper.ValidatedPartUri x, PackUriHelper.ValidatedPartUri y)

Check warning on line 1108 in src/DocumentFormat.OpenXml.Flatten/DocumentFormat.OpenXml.Flatten/Compatibilities/Packaging/CompatiblePackage.cs

View workflow job for this annotation

GitHub Actions / build

Nullability of reference types in type of parameter 'x' of 'bool ValidatedPartUriIgnoreCaseEqualityComparer.Equals(ValidatedPartUri x, ValidatedPartUri y)' doesn't match implicitly implemented member 'bool IEqualityComparer<ValidatedPartUri>.Equals(ValidatedPartUri x, ValidatedPartUri y)' (possibly because of nullability attributes).

Check warning on line 1108 in src/DocumentFormat.OpenXml.Flatten/DocumentFormat.OpenXml.Flatten/Compatibilities/Packaging/CompatiblePackage.cs

View workflow job for this annotation

GitHub Actions / build

Nullability of reference types in type of parameter 'y' of 'bool ValidatedPartUriIgnoreCaseEqualityComparer.Equals(ValidatedPartUri x, ValidatedPartUri y)' doesn't match implicitly implemented member 'bool IEqualityComparer<ValidatedPartUri>.Equals(ValidatedPartUri x, ValidatedPartUri y)' (possibly because of nullability attributes).
{
return StringComparer.OrdinalIgnoreCase.Equals(x.NormalizedPartUriString, y.NormalizedPartUriString);
}

public int GetHashCode(PackUriHelper.ValidatedPartUri obj)
{
return StringComparer.OrdinalIgnoreCase.GetHashCode(obj.NormalizedPartUriString);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ protected override string GetContentTypeCore()
//Step 2: 通过路径进行特殊判断
// 例如 Slide 几的页面路径
var uri = partUri.OriginalString;
if (Regex.IsMatch(uri, @"/ppt/slides/slide\d+.xml"))
if (Regex.IsMatch(uri, @"/ppt/slides/slide\d+\.xml"))
{
// "/ppt/slides/slide0.xml"
return new CompatiblePackage.ContentType(
Expand Down Expand Up @@ -84,6 +84,20 @@ protected override string GetContentTypeCore()
return new CompatiblePackage.ContentType("application/vnd.openxmlformats-officedocument.presentationml.notesMaster+xml");
}

if (Regex.IsMatch(uri, @"/ppt/diagrams/drawing\d+\.xml"))
{
// /ppt/diagrams/drawing0.xml
// application/vnd.ms-office.drawingml.diagramDrawing+xml
return new CompatiblePackage.ContentType("application/vnd.ms-office.drawingml.diagramDrawing+xml");
}

if (Regex.IsMatch(uri, @"/tags/tag\d+\.xml"))
{
// /tags/tag0.xml
// application/vnd.openxmlformats-officedocument.presentationml.tags+xml
return new CompatiblePackage.ContentType("application/vnd.openxmlformats-officedocument.presentationml.tags+xml");
}

//Step 3: Check if there is a default entry corresponding to the
//extension of the partUri provided.
string extension = partUri.PartUriExtension;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,19 @@ public readonly struct ShapePath
/// 创建PPT的Geometry Path
/// </summary>
/// <param name="path">OpenXml Path字符串</param>
/// <param name="fillMode">OpenXml的Path Fill Mode </param>
/// <param name="isStroke">是否有轮廓</param>
/// <param name="isExtrusionOk">指定使用 3D 拉伸可能在此路径</param>
/// <param name="fillMode">OpenXml的Path Fill Mode:默认为Norm </param>
/// <param name="isStroke">是否有轮廓:默认为True</param>
/// <param name="isExtrusionOk">指定使用 3D 拉伸可能在此路径:默认为False</param>
/// <param name="emuWidth">指定的宽度或在路径坐标系统中应在使用的最大的 x 坐标</param>
/// <param name="emuHeight">指定框架的高度或在路径坐标系统中应在使用的最大的 y 坐标</param>
public ShapePath(string path, PathFillModeValues fillMode = PathFillModeValues.Norm, bool isStroke = true, bool isExtrusionOk = false, double? emuWidth = null, double? emuHeight = null)
/// <remarks>参考文档:Ecma Office Open XML Part 1 - Fundamentals And Markup Language Reference - 20.1.9.15 path (Shape Path)</remarks>
public ShapePath(string path, PathFillModeValues? fillMode = PathFillModeValues.Norm, bool? isStroke = true, bool? isExtrusionOk = false, double? emuWidth = null, double? emuHeight = null)
{
Path = path;
IsStroke = isStroke;
FillMode = fillMode;
IsStroke = isStroke ?? true;
FillMode = fillMode ?? PathFillModeValues.Norm;
IsFilled = fillMode is not PathFillModeValues.None;
IsExtrusionOk = isExtrusionOk;
IsExtrusionOk = isExtrusionOk ?? false;
Width = emuWidth.HasValue ? new Emu(emuWidth.Value) : null;
Height = emuHeight.HasValue ? new Emu(emuHeight.Value) : null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,17 @@ internal static ITransformData CreateTransformData(this OpenXmlElement element,
return transformData;
}

var alternateContentTransform2D = element.GetFirstChild<ContentPart>()?.GetFirstChild<DocumentFormat.OpenXml.Office2010.PowerPoint.Transform2D>();
if (alternateContentTransform2D is not null)
{
FillOffset(alternateContentTransform2D.Offset, transformData);
FillExtents(alternateContentTransform2D.Extents, transformData);
FillRotation(alternateContentTransform2D.Rotation, transformData);
FillFlip(alternateContentTransform2D.HorizontalFlip, alternateContentTransform2D.VerticalFlip, transformData);
return transformData;
}


return transformData;

void FillOffset(Offset? offset, TransformData transformData2)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Globalization;
using System.Diagnostics;
using System.Globalization;

using DocumentFormat.OpenXml.Drawing;
using DocumentFormat.OpenXml.Flatten.Framework.Context;
Expand Down Expand Up @@ -295,14 +296,37 @@ public static class ColorHelper
/// <returns></returns>
public static Color? ToColor(this RgbColorModelHex color)
{
if (color.Val is not null)
if (color.Val is null)
{
if (uint.TryParse(color.Val.Value, NumberStyles.HexNumber, null, out var result))
{
var solidColor = result.HexToColor();
var modifiedColor = ColorTransform.AppendColorModify(solidColor, color.ChildElements);
return modifiedColor;
}
return null;
}

var solidColor = ToColor(color.Val.Value);
if (solidColor is null)
{
return null;
}
var modifiedColor = ColorTransform.AppendColorModify(solidColor, color.ChildElements);
return modifiedColor;

}

/// <summary>
/// 将<see cref="string" />颜色值转换为<see cref="Color" />
/// </summary>
/// <param name="colorValue">颜色值:例如#E71224</param>
/// <returns></returns>
public static Color? ToColor(this string? colorValue)
{
if (string.IsNullOrEmpty(colorValue))
{
return null;
}

var (success, a, r, g, b) = ConvertToColor(colorValue!);
if (success)
{
return new(a, r, g, b);
}

return null;
Expand Down Expand Up @@ -358,6 +382,121 @@ private static Color HexToColor(this uint rgb)
return color;
}

/// <summary>
/// 将传入的颜色字符串转换为颜色输出
/// </summary>
/// <param name="hexColorText">颜色字符串,格式如 “#FFDFD991” 或 “#DFD991”等,规则和 WPF 的 XAML 颜色相同,其中 “#” 是可选的</param>
/// <returns></returns>
public static (bool success, byte a, byte r, byte g, byte b) ConvertToColor(string hexColorText)
{
#if NET6_0_OR_GREATER
bool startWithPoundSign = hexColorText.StartsWith('#');
#else
bool startWithPoundSign = hexColorText.StartsWith("#");
#endif
var colorStringLength = hexColorText.Length;
if (startWithPoundSign) colorStringLength -= 1;
int currentOffset = startWithPoundSign ? 1 : 0;
// 可以采用的格式如下
// #FFDFD991 8 个字符 存在 Alpha 通道
// #DFD991 6 个字符
// #FD92 4 个字符 存在 Alpha 通道
// #DAC 3 个字符
if (colorStringLength == 8
|| colorStringLength == 6
|| colorStringLength == 4
|| colorStringLength == 3)
{
bool success;
byte result;
byte a;

int readCount;
// #DFD991 6 个字符
// #FFDFD991 8 个字符 存在 Alpha 通道
//if (colorStringLength == 8 || colorStringLength == 6)
if (colorStringLength > 5)
{
readCount = 2;
}
else
{
readCount = 1;
}

bool includeAlphaChannel = colorStringLength == 8 || colorStringLength == 4;

if (includeAlphaChannel)
{
(success, result) = HexCharToNumber(hexColorText, currentOffset, readCount);
if (!success) return default;
a = result;
currentOffset += readCount;
}
else
{
a = 0xFF;
}

(success, result) = HexCharToNumber(hexColorText, currentOffset, readCount);
if (!success) return default;
byte r = result;
currentOffset += readCount;

(success, result) = HexCharToNumber(hexColorText, currentOffset, readCount);
if (!success) return default;
byte g = result;
currentOffset += readCount;

(success, result) = HexCharToNumber(hexColorText, currentOffset, readCount);
if (!success) return default;
byte b = result;

return (true, a, r, g, b);
}

return default;
}

static (bool success, byte result) HexCharToNumber(string input, int offset, int readCount)
{
Debug.Assert(readCount == 1 || readCount == 2, "要求 readCount 只能是 1 或者 2 的值,这是框架限制,因此不做判断");

byte result = 0;

for (int i = 0; i < readCount; i++, offset++)
{
var c = input[offset];
byte n;
if (c >= '0' && c <= '9')
{
n = (byte) (c - '0');
}
else if (c >= 'a' && c <= 'f')
{
n = (byte) (c - 'a' + 10);
}
else if (c >= 'A' && c <= 'F')
{
n = (byte) (c - 'A' + 10);
}
else
{
return default;
}

result *= 16;
result += n;
}

if (readCount == 1)
{
result = (byte) (result * 16 + result);
}

return (true, result);
}

//private static ColorBrush? ToColorBrush([CanBeNull] this Color? color)
//{
// if (color == null) return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public CustomGeometryConverter(CustomGeometry customGeometry, ElementEmuSize emu
/// <returns></returns>
public SvgPath? Convert()
{
ConvertAdjustValueList();
ConvertShapeGuideList();
ConvertShapeTextRectangle();
return ConvertPathList();
Expand Down Expand Up @@ -67,6 +68,25 @@ private void ConvertShapeTextRectangle()
ShapeTextRectangle = new EmuShapeTextRectangle(left, top, right, bottom);
}

private void ConvertAdjustValueList()
{
var adjustValueList = _customGeometry.AdjustValueList;
if (adjustValueList is not null)
{
foreach (var shapeGuide in adjustValueList.Elements().OfType<ShapeGuide>())
{
var name = shapeGuide.Name?.Value;
var formula = shapeGuide.Formula?.Value;

if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(formula))
{
ShapeGeometryFormulaCalculator.Calculate(name!, formula!);
}
}
}
}


private void ConvertShapeGuideList()
{
var shapeGuideList = _customGeometry.ShapeGuideList;
Expand All @@ -83,6 +103,7 @@ private void ConvertShapeGuideList()
}
}
}

}

private SvgPath? ConvertPathList()
Expand Down Expand Up @@ -134,7 +155,13 @@ void TryClosePath()
}
}

svgPathList.Add(new ShapePath(stringPath.ToString()));
var pathFillModeValues = path.Fill?.Value;
var isStroke = path.Stroke?.Value;
var width = path.Width?.Value;
var height = path.Height?.Value;
var isExtrusionOk = path.ExtrusionOk?.Value;

svgPathList.Add(new ShapePath(stringPath.ToString(), pathFillModeValues, isStroke, isExtrusionOk, width, height));
stringPath.Clear();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Xml.Linq;

using DocumentFormat.OpenXml.Drawing;
Expand Down Expand Up @@ -268,11 +269,27 @@ public static class ShapeGeometryConverterHelper
return default;
}

var path = shapeGeometryBase.ToGeometryPathString(emuSize, adjustList);
var multiGeometryPaths = shapeGeometryBase.GetMultiShapePaths(emuSize, adjustList);

var pathString = shapeGeometryBase.ToGeometryPathString(emuSize, adjustList);
var path = string.IsNullOrWhiteSpace(pathString) ? GetSvgPath(multiGeometryPaths) : pathString;
return new SvgPath(geometryShapeTypeValues, path, shapeGeometryBase.ShapeTextRectangle, multiGeometryPaths);
}

private static string? GetSvgPath(ShapePath[]? shapePaths)
{
if (shapePaths is not null)
{
var sb = new StringBuilder();
foreach (var shapePath in shapePaths)
{
sb.Append(shapePath.Path);
}
return sb.ToString();
}
return default;
}

/// <summary>
/// 根据调整点Name获取调整点的Value
/// </summary>
Expand Down
Loading

0 comments on commit 6602f56

Please sign in to comment.