<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[197600] trunk/Source/WebCore</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/197600">197600</a></dd>
<dt>Author</dt> <dd>timothy_horton@apple.com</dd>
<dt>Date</dt> <dd>2016-03-04 16:57:19 -0800 (Fri, 04 Mar 2016)</dd>
</dl>
<h3>Log Message</h3>
<pre>Begin implementing <attachment> painting on iOS
https://bugs.webkit.org/show_bug.cgi?id=155046
<rdar://problem/24805991>
Reviewed by Enrica Casucci.
No new tests; there are existing tests that I will unskip and rebaseline
in the near future.
* rendering/RenderThemeIOS.h:
* rendering/RenderThemeIOS.mm:
(WebCore::AttachmentInfo::addLine):
(WebCore::AttachmentInfo::buildTitleLines):
(WebCore::AttachmentInfo::buildSingleLine):
(WebCore::getAttachmentProgress):
(WebCore::iconForAttachment):
(WebCore::AttachmentInfo::AttachmentInfo):
(WebCore::RenderThemeIOS::attachmentIntrinsicSize):
(WebCore::RenderThemeIOS::attachmentBaseline):
(WebCore::paintAttachmentIcon):
(WebCore::paintAttachmentText):
(WebCore::paintAttachmentProgress):
(WebCore::paintAttachmentBorder):
(WebCore::RenderThemeIOS::paintAttachment):
There are still a few missing pieces, but get <attachment> painting a bit on iOS.
We will paint an icon, action, title, and subtitle - in that order - depending on what we have.
The content is vertically and horizontally centered.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderThemeIOSh">trunk/Source/WebCore/rendering/RenderThemeIOS.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderThemeIOSmm">trunk/Source/WebCore/rendering/RenderThemeIOS.mm</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (197599 => 197600)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-03-05 00:56:07 UTC (rev 197599)
+++ trunk/Source/WebCore/ChangeLog        2016-03-05 00:57:19 UTC (rev 197600)
</span><span class="lines">@@ -1,3 +1,33 @@
</span><ins>+2016-03-04 Tim Horton <timothy_horton@apple.com>
+
+ Begin implementing <attachment> painting on iOS
+ https://bugs.webkit.org/show_bug.cgi?id=155046
+ <rdar://problem/24805991>
+
+ Reviewed by Enrica Casucci.
+
+ No new tests; there are existing tests that I will unskip and rebaseline
+ in the near future.
+
+ * rendering/RenderThemeIOS.h:
+ * rendering/RenderThemeIOS.mm:
+ (WebCore::AttachmentInfo::addLine):
+ (WebCore::AttachmentInfo::buildTitleLines):
+ (WebCore::AttachmentInfo::buildSingleLine):
+ (WebCore::getAttachmentProgress):
+ (WebCore::iconForAttachment):
+ (WebCore::AttachmentInfo::AttachmentInfo):
+ (WebCore::RenderThemeIOS::attachmentIntrinsicSize):
+ (WebCore::RenderThemeIOS::attachmentBaseline):
+ (WebCore::paintAttachmentIcon):
+ (WebCore::paintAttachmentText):
+ (WebCore::paintAttachmentProgress):
+ (WebCore::paintAttachmentBorder):
+ (WebCore::RenderThemeIOS::paintAttachment):
+ There are still a few missing pieces, but get <attachment> painting a bit on iOS.
+ We will paint an icon, action, title, and subtitle - in that order - depending on what we have.
+ The content is vertically and horizontally centered.
+
</ins><span class="cx"> 2016-03-04 Gavin Barraclough <barraclough@apple.com>
</span><span class="cx">
</span><span class="cx"> Convert DOMTimer interval from int to std::chromo::milliseconds
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderThemeIOSh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderThemeIOS.h (197599 => 197600)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderThemeIOS.h        2016-03-05 00:56:07 UTC (rev 197599)
+++ trunk/Source/WebCore/rendering/RenderThemeIOS.h        2016-03-05 00:57:19 UTC (rev 197600)
</span><span class="lines">@@ -34,7 +34,8 @@
</span><span class="cx">
</span><span class="cx"> class RenderStyle;
</span><span class="cx"> class GraphicsContext;
</span><del>-
</del><ins>+struct AttachmentLayout;
+
</ins><span class="cx"> class RenderThemeIOS final : public RenderTheme {
</span><span class="cx"> public:
</span><span class="cx"> static Ref<RenderTheme> create();
</span><span class="lines">@@ -110,6 +111,12 @@
</span><span class="cx"> String mediaControlsScript() override;
</span><span class="cx"> #endif
</span><span class="cx">
</span><ins>+#if ENABLE(ATTACHMENT_ELEMENT)
+ LayoutSize attachmentIntrinsicSize(const RenderAttachment&) const override;
+ int attachmentBaseline(const RenderAttachment&) const override;
+ bool paintAttachment(const RenderObject&, const PaintInfo&, const IntRect&) override;
+#endif
+
</ins><span class="cx"> private:
</span><span class="cx"> RenderThemeIOS();
</span><span class="cx"> virtual ~RenderThemeIOS() { }
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderThemeIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderThemeIOS.mm (197599 => 197600)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderThemeIOS.mm        2016-03-05 00:56:07 UTC (rev 197599)
+++ trunk/Source/WebCore/rendering/RenderThemeIOS.mm        2016-03-05 00:57:19 UTC (rev 197600)
</span><span class="lines">@@ -27,20 +27,25 @@
</span><span class="cx">
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">
</span><ins>+#import "BitmapImage.h"
</ins><span class="cx"> #import "CSSPrimitiveValue.h"
</span><span class="cx"> #import "CSSToLengthConversionData.h"
</span><span class="cx"> #import "CSSValueKeywords.h"
</span><span class="cx"> #import "CoreTextSPI.h"
</span><span class="cx"> #import "DateComponents.h"
</span><span class="cx"> #import "Document.h"
</span><ins>+#import "File.h"
</ins><span class="cx"> #import "FloatRoundedRect.h"
</span><span class="cx"> #import "FontCache.h"
</span><span class="cx"> #import "FontCascade.h"
</span><span class="cx"> #import "Frame.h"
</span><ins>+#import "FrameSelection.h"
</ins><span class="cx"> #import "FrameView.h"
</span><ins>+#import "GeometryUtilities.h"
</ins><span class="cx"> #import "Gradient.h"
</span><span class="cx"> #import "GraphicsContext.h"
</span><span class="cx"> #import "GraphicsContextCG.h"
</span><ins>+#import "HTMLAttachmentElement.h"
</ins><span class="cx"> #import "HTMLInputElement.h"
</span><span class="cx"> #import "HTMLNames.h"
</span><span class="cx"> #import "HTMLSelectElement.h"
</span><span class="lines">@@ -49,7 +54,9 @@
</span><span class="cx"> #import "NodeRenderStyle.h"
</span><span class="cx"> #import "Page.h"
</span><span class="cx"> #import "PaintInfo.h"
</span><ins>+#import "PathUtilities.h"
</ins><span class="cx"> #import "PlatformLocale.h"
</span><ins>+#import "RenderAttachment.h"
</ins><span class="cx"> #import "RenderObject.h"
</span><span class="cx"> #import "RenderProgress.h"
</span><span class="cx"> #import "RenderStyle.h"
</span><span class="lines">@@ -57,6 +64,7 @@
</span><span class="cx"> #import "RenderView.h"
</span><span class="cx"> #import "SoftLinking.h"
</span><span class="cx"> #import "UIKitSPI.h"
</span><ins>+#import "UTIUtilities.h"
</ins><span class="cx"> #import "UserAgentScripts.h"
</span><span class="cx"> #import "UserAgentStyleSheets.h"
</span><span class="cx"> #import "WebCoreThreadRun.h"
</span><span class="lines">@@ -66,10 +74,18 @@
</span><span class="cx"> #import <wtf/RefPtr.h>
</span><span class="cx"> #import <wtf/StdLibExtras.h>
</span><span class="cx">
</span><ins>+SOFT_LINK_FRAMEWORK(MobileCoreServices)
+SOFT_LINK_CLASS(MobileCoreServices, LSDocumentProxy)
+
</ins><span class="cx"> SOFT_LINK_FRAMEWORK(UIKit)
</span><span class="cx"> SOFT_LINK_CLASS(UIKit, UIApplication)
</span><span class="cx"> SOFT_LINK_CLASS(UIKit, UIColor)
</span><ins>+SOFT_LINK_CLASS(UIKit, UIDocumentInteractionController)
+SOFT_LINK_CLASS(UIKit, UIFont)
+SOFT_LINK_CLASS(UIKit, UIImage)
</ins><span class="cx"> SOFT_LINK_CONSTANT(UIKit, UIContentSizeCategoryDidChangeNotification, CFStringRef)
</span><ins>+SOFT_LINK_CONSTANT(UIKit, UIFontTextStyleFootnote, NSString *)
+SOFT_LINK_CONSTANT(UIKit, UIFontTextStyleCaption1, NSString *)
</ins><span class="cx"> #define UIContentSizeCategoryDidChangeNotification getUIContentSizeCategoryDidChangeNotification()
</span><span class="cx">
</span><span class="cx"> @interface WebCoreRenderThemeBundle : NSObject
</span><span class="lines">@@ -80,6 +96,8 @@
</span><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><ins>+using namespace HTMLNames;
+
</ins><span class="cx"> const float ControlBaseHeight = 20;
</span><span class="cx"> const float ControlBaseFontSize = 11;
</span><span class="cx">
</span><span class="lines">@@ -1321,6 +1339,320 @@
</span><span class="cx"> return addResult.iterator->value;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if ENABLE(ATTACHMENT_ELEMENT)
+
+const CGSize attachmentSize = { 160, 119 };
+
+const CGFloat attachmentBorderRadius = 16;
+static Color attachmentBorderColor() { return Color(204, 204, 204); }
+
+const CGFloat attachmentProgressSize = 36;
+const CGFloat attachmentIconSize = 48;
+
+const CGFloat attachmentItemMargin = 8;
+
+const CGFloat attachmentTitleMaximumWidth = 140;
+const CFIndex attachmentTitleMaximumLineCount = 2;
+
+// FIXME: Should be emphasized.
+static UIFont *attachmentActionFont() { return [getUIFontClass() preferredFontForTextStyle:getUIFontTextStyleFootnote()]; }
+static UIColor *attachmentActionColor() { return [getUIColorClass() systemBlueColor]; }
+
+static UIFont *attachmentTitleFont() { return [getUIFontClass() preferredFontForTextStyle:getUIFontTextStyleCaption1()]; }
+static UIColor *attachmentTitleColor() { return [getUIColorClass() systemGrayColor]; }
+
+static UIFont *attachmentSubtitleFont() { return [getUIFontClass() preferredFontForTextStyle:getUIFontTextStyleCaption1()]; }
+static UIColor *attachmentSubtitleColor() { return [getUIColorClass() systemGrayColor]; }
+
+struct AttachmentInfo {
+ explicit AttachmentInfo(const RenderAttachment&);
+
+ FloatRect iconRect;
+ FloatRect attachmentRect;
+ FloatRect progressRect;
+
+ BOOL hasProgress { NO };
+ float progress;
+
+ RetainPtr<UIImage> icon;
+
+ int baseline { 0 };
+
+ struct LabelLine {
+ FloatRect rect;
+ RetainPtr<CTLineRef> line;
+ };
+ Vector<LabelLine> lines;
+
+ CGFloat contentYOrigin { 0 };
+
+private:
+ void buildTitleLines(const RenderAttachment&);
+ void buildSingleLine(const String&, UIFont *, UIColor *);
+
+ void addLine(CTLineRef);
+};
+
+void AttachmentInfo::addLine(CTLineRef line)
+{
+ CGRect lineBounds = CTLineGetBoundsWithOptions(line, kCTLineBoundsExcludeTypographicLeading);
+ CGFloat trailingWhitespaceWidth = CTLineGetTrailingWhitespaceWidth(line);
+ CGFloat lineWidthIgnoringTrailingWhitespace = lineBounds.size.width - trailingWhitespaceWidth;
+ CGFloat lineHeight = CGCeiling(lineBounds.size.height + lineBounds.origin.y);
+
+ CGFloat xOffset = (attachmentRect.width() / 2) - (lineWidthIgnoringTrailingWhitespace / 2);
+ LabelLine labelLine;
+ labelLine.line = line;
+ labelLine.rect = FloatRect(xOffset, 0, lineWidthIgnoringTrailingWhitespace, lineHeight);
+
+ lines.append(labelLine);
</ins><span class="cx"> }
</span><span class="cx">
</span><ins>+void AttachmentInfo::buildTitleLines(const RenderAttachment& attachment)
+{
+ RetainPtr<UIFont> font = attachmentTitleFont();
+
+ String title = attachment.attachmentElement().attachmentTitle();
+ if (title.isEmpty())
+ return;
+
+ NSDictionary *textAttributes = @{
+ (id)kCTFontAttributeName: font.get(),
+ (id)kCTForegroundColorAttributeName: attachmentTitleColor()
+ };
+ RetainPtr<NSAttributedString> attributedTitle = adoptNS([[NSAttributedString alloc] initWithString:title attributes:textAttributes]);
+ RetainPtr<CTFramesetterRef> titleFramesetter = adoptCF(CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attributedTitle.get()));
+
+ CFRange fitRange;
+ CGSize titleTextSize = CTFramesetterSuggestFrameSizeWithConstraints(titleFramesetter.get(), CFRangeMake(0, 0), nullptr, CGSizeMake(attachmentTitleMaximumWidth, CGFLOAT_MAX), &fitRange);
+
+ RetainPtr<CGPathRef> titlePath = adoptCF(CGPathCreateWithRect(CGRectMake(0, 0, titleTextSize.width, titleTextSize.height), nullptr));
+ RetainPtr<CTFrameRef> titleFrame = adoptCF(CTFramesetterCreateFrame(titleFramesetter.get(), fitRange, titlePath.get(), nullptr));
+
+ CFArrayRef ctLines = CTFrameGetLines(titleFrame.get());
+ CFIndex lineCount = CFArrayGetCount(ctLines);
+ if (!lineCount)
+ return;
+
+ // Lay out and record the first (attachmentTitleMaximumLineCount - 1) lines.
+ CFIndex lineIndex = 0;
+ for (; lineIndex < std::min(attachmentTitleMaximumLineCount - 1, lineCount); ++lineIndex) {
+ CTLineRef line = (CTLineRef)CFArrayGetValueAtIndex(ctLines, lineIndex);
+ addLine(line);
+ }
+
+ if (lineIndex == lineCount)
+ return;
+
+ // We had text that didn't fit in the first (attachmentTitleMaximumLineCount - 1) lines.
+ // Combine it into one last line, and center-truncate it.
+ CTLineRef firstRemainingLine = (CTLineRef)CFArrayGetValueAtIndex(ctLines, lineIndex);
+ CFIndex remainingRangeStart = CTLineGetStringRange(firstRemainingLine).location;
+ NSRange remainingRange = NSMakeRange(remainingRangeStart, [attributedTitle length] - remainingRangeStart);
+ NSAttributedString *remainingString = [attributedTitle attributedSubstringFromRange:remainingRange];
+ RetainPtr<CTLineRef> remainingLine = adoptCF(CTLineCreateWithAttributedString((CFAttributedStringRef)remainingString));
+ RetainPtr<NSAttributedString> ellipsisString = adoptNS([[NSAttributedString alloc] initWithString:@"\u2026" attributes:textAttributes]);
+ RetainPtr<CTLineRef> ellipsisLine = adoptCF(CTLineCreateWithAttributedString((CFAttributedStringRef)ellipsisString.get()));
+ RetainPtr<CTLineRef> truncatedLine = adoptCF(CTLineCreateTruncatedLine(remainingLine.get(), attachmentTitleMaximumWidth, kCTLineTruncationMiddle, ellipsisLine.get()));
+
+ if (!truncatedLine)
+ truncatedLine = remainingLine;
+
+ addLine(truncatedLine.get());
+}
+
+void AttachmentInfo::buildSingleLine(const String& text, UIFont *font, UIColor *color)
+{
+ if (text.isEmpty())
+ return;
+
+ NSDictionary *textAttributes = @{
+ (id)kCTFontAttributeName: font,
+ (id)kCTForegroundColorAttributeName: color
+ };
+ RetainPtr<NSAttributedString> attributedText = adoptNS([[NSAttributedString alloc] initWithString:text attributes:textAttributes]);
+
+ addLine(adoptCF(CTLineCreateWithAttributedString((CFAttributedStringRef)attributedText.get())).get());
+}
+
+static BOOL getAttachmentProgress(const RenderAttachment& attachment, float& progress)
+{
+ String progressString = attachment.attachmentElement().fastGetAttribute(progressAttr);
+ if (progressString.isEmpty())
+ return NO;
+ bool validProgress;
+ progress = progressString.toFloat(&validProgress);
+ return validProgress;
+}
+
+static RetainPtr<UIImage> iconForAttachment(const RenderAttachment& attachment, FloatSize& size)
+{
+ String MIMEType = attachment.attachmentElement().attachmentType();
+
+ String fileName;
+ if (File* file = attachment.attachmentElement().file())
+ fileName = file->name();
+
+ if (fileName.isEmpty())
+ fileName = attachment.attachmentElement().attachmentTitle();
+
+ RetainPtr<UIImage> result;
+
+ RetainPtr<UIDocumentInteractionController> documentInteractionController = adoptNS([[getUIDocumentInteractionControllerClass() alloc] init]);
+ [documentInteractionController setName:fileName];
+ [documentInteractionController setUTI:static_cast<NSString *>(mimeTypeFromUTITree(MIMEType.createCFString().get()).get())];
+
+ NSArray *icons = [documentInteractionController icons];
+ if (!icons.count)
+ return nil;
+
+ result = icons.lastObject;
+
+ BOOL useHeightForClosestMatch = [result size].height > [result size].width;
+ CGFloat bestMatchRatio = -1;
+
+ for (UIImage *icon in icons) {
+ CGFloat iconSize = useHeightForClosestMatch ? icon.size.height : icon.size.width;
+
+ CGFloat matchRatio = (attachmentIconSize / iconSize) - 1.0f;
+ if (matchRatio < 0.3f) {
+ matchRatio = CGFAbs(matchRatio);
+ if ((bestMatchRatio == -1) || (matchRatio < bestMatchRatio)) {
+ result = icon;
+ bestMatchRatio = matchRatio;
+ }
+ }
+ }
+
+ CGFloat iconAspect = [result size].width / [result size].height;
+ size = largestRectWithAspectRatioInsideRect(iconAspect, FloatRect(0, 0, attachmentIconSize, attachmentIconSize)).size();
+
+ return result;
+}
+
+AttachmentInfo::AttachmentInfo(const RenderAttachment& attachment)
+{
+ attachmentRect = FloatRect(0, 0, attachmentSize.width, attachmentSize.height);
+
+ hasProgress = getAttachmentProgress(attachment, progress);
+
+ String action = attachment.attachmentElement().fastGetAttribute(actionAttr);
+ String subtitle = attachment.attachmentElement().fastGetAttribute(subtitleAttr);
+
+ CGFloat yOffset = 0;
+
+ if (hasProgress) {
+ progressRect = FloatRect((attachmentRect.width() / 2) - (attachmentProgressSize / 2), 0, attachmentProgressSize, attachmentProgressSize);
+ yOffset += attachmentProgressSize + attachmentItemMargin;
+ }
+
+ if (action.isEmpty() && !hasProgress) {
+ FloatSize iconSize;
+ icon = iconForAttachment(attachment, iconSize);
+ if (icon) {
+ iconRect = FloatRect(FloatPoint((attachmentRect.width() / 2) - (iconSize.width() / 2), 0), iconSize);
+ yOffset += iconRect.height() + attachmentItemMargin;
+ }
+ } else
+ buildSingleLine(action, attachmentActionFont(), attachmentActionColor());
+
+ buildTitleLines(attachment);
+ buildSingleLine(subtitle, attachmentSubtitleFont(), attachmentSubtitleColor());
+
+ if (!lines.isEmpty()) {
+ for (auto& line : lines) {
+ line.rect.setY(yOffset);
+ yOffset += line.rect.height() + attachmentItemMargin;
+ }
+ }
+
+ contentYOrigin = (attachmentRect.height() / 2) - (yOffset / 2);
+}
+
+LayoutSize RenderThemeIOS::attachmentIntrinsicSize(const RenderAttachment&) const
+{
+ return LayoutSize(FloatSize(attachmentSize));
+}
+
+int RenderThemeIOS::attachmentBaseline(const RenderAttachment& attachment) const
+{
+ AttachmentInfo info(attachment);
+ return info.baseline;
+}
+
+static void paintAttachmentIcon(GraphicsContext& context, AttachmentInfo& info)
+{
+ if (!info.icon)
+ return;
+
+ RefPtr<Image> iconImage = BitmapImage::create([info.icon CGImage]);
+ if (!iconImage)
+ return;
+
+ context.drawImage(*iconImage, info.iconRect);
+}
+
+
+static void paintAttachmentText(GraphicsContext& context, AttachmentInfo& info)
+{
+ for (const auto& line : info.lines) {
+ GraphicsContextStateSaver saver(context);
+
+ context.translate(toFloatSize(line.rect.minXMaxYCorner()));
+ context.scale(FloatSize(1, -1));
+
+ CGContextSetTextMatrix(context.platformContext(), CGAffineTransformIdentity);
+ CTLineDraw(line.line.get(), context.platformContext());
+ }
+}
+
+static void paintAttachmentProgress(GraphicsContext& context, AttachmentInfo& info)
+{
+ GraphicsContextStateSaver saver(context);
+
+ // FIXME: Implement progress indicator.
+ context.fillRect(info.progressRect, Color(0, 255, 0));
+}
+
+static void paintAttachmentBorder(GraphicsContext& context, AttachmentInfo& info)
+{
+ Path borderPath;
+ borderPath.addRoundedRect(info.attachmentRect, FloatSize(attachmentBorderRadius, attachmentBorderRadius));
+ context.setStrokeColor(attachmentBorderColor());
+ context.setStrokeThickness(1);
+ context.strokePath(borderPath);
+}
+
+bool RenderThemeIOS::paintAttachment(const RenderObject& renderer, const PaintInfo& paintInfo, const IntRect& paintRect)
+{
+ if (!is<RenderAttachment>(renderer))
+ return false;
+
+ const RenderAttachment& attachment = downcast<RenderAttachment>(renderer);
+
+ AttachmentInfo info(attachment);
+
+ GraphicsContext& context = paintInfo.context();
+ GraphicsContextStateSaver saver(context);
+
+ context.translate(toFloatSize(paintRect.location()));
+
+ paintAttachmentBorder(context, info);
+
+ context.translate(FloatSize(0, info.contentYOrigin));
+
+ if (info.hasProgress)
+ paintAttachmentProgress(context, info);
+ else if (info.icon)
+ paintAttachmentIcon(context, info);
+
+ paintAttachmentText(context, info);
+
+ return true;
+}
+
+#endif // ENABLE(ATTACHMENT_ELEMENT)
+
+} // namespace WebCore
+
</ins><span class="cx"> #endif //PLATFORM(IOS)
</span></span></pre>
</div>
</div>
</body>
</html>