1/* 2 * Copyright (C) 2009 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#if PLATFORM(IOS) 27 28#import "WebSelectionRect.h" 29 30@implementation WebSelectionRect 31 32@synthesize rect = m_rect; 33@synthesize writingDirection = m_writingDirection; 34@synthesize isLineBreak = m_isLineBreak; 35@synthesize isFirstOnLine = m_isFirstOnLine; 36@synthesize isLastOnLine = m_isLastOnLine; 37@synthesize containsStart = m_containsStart; 38@synthesize containsEnd = m_containsEnd; 39@synthesize isInFixedPosition = m_isInFixedPosition; 40@synthesize isHorizontal = m_isHorizontal; 41 42+ (WebSelectionRect *)selectionRect 43{ 44 return [[[self alloc] init] autorelease]; 45} 46 47+ (CGRect)startEdge:(NSArray *)rects 48{ 49 if (rects.count == 0) 50 return CGRectZero; 51 52 WebSelectionRect *selectionRect = nil; 53 for (WebSelectionRect *srect in rects) { 54 if (srect.containsStart) { 55 selectionRect = srect; 56 break; 57 } 58 } 59 if (!selectionRect) 60 selectionRect = [rects objectAtIndex:0]; 61 62 CGRect rect = selectionRect.rect; 63 64 if (!selectionRect.isHorizontal) { 65 switch (selectionRect.writingDirection) { 66 case WKWritingDirectionNatural: 67 case WKWritingDirectionLeftToRight: 68 // collapse to top edge 69 rect.size.height = 1; 70 break; 71 case WKWritingDirectionRightToLeft: 72 // collapse to bottom edge 73 rect.origin.y += (rect.size.height - 1); 74 rect.size.height = 1; 75 break; 76 } 77 return rect; 78 } 79 80 switch (selectionRect.writingDirection) { 81 case WKWritingDirectionNatural: 82 case WKWritingDirectionLeftToRight: 83 // collapse to left edge 84 rect.size.width = 1; 85 break; 86 case WKWritingDirectionRightToLeft: 87 // collapse to right edge 88 rect.origin.x += (rect.size.width - 1); 89 rect.size.width = 1; 90 break; 91 } 92 return rect; 93} 94 95+ (CGRect)endEdge:(NSArray *)rects 96{ 97 if (rects.count == 0) 98 return CGRectZero; 99 100 WebSelectionRect *selectionRect = nil; 101 for (WebSelectionRect *srect in rects) { 102 if (srect.containsEnd) { 103 selectionRect = srect; 104 break; 105 } 106 } 107 if (!selectionRect) 108 selectionRect = [rects lastObject]; 109 110 CGRect rect = selectionRect.rect; 111 112 if (!selectionRect.isHorizontal) { 113 switch (selectionRect.writingDirection) { 114 case WKWritingDirectionNatural: 115 case WKWritingDirectionLeftToRight: 116 // collapse to bottom edge 117 rect.origin.y += (rect.size.height - 1); 118 rect.size.height = 1; 119 break; 120 case WKWritingDirectionRightToLeft: 121 // collapse to top edge 122 rect.size.height = 1; 123 break; 124 } 125 return rect; 126 } 127 128 switch (selectionRect.writingDirection) { 129 case WKWritingDirectionNatural: 130 case WKWritingDirectionLeftToRight: 131 // collapse to right edge 132 rect.origin.x += (rect.size.width - 1); 133 rect.size.width = 1; 134 break; 135 case WKWritingDirectionRightToLeft: 136 // collapse to left edge 137 rect.size.width = 1; 138 break; 139 } 140 return rect; 141} 142 143- (id)init 144{ 145 self = [super init]; 146 if (!self) 147 return nil; 148 149 self.rect = CGRectZero; 150 self.writingDirection = WKWritingDirectionLeftToRight; 151 self.isLineBreak = NO; 152 self.isFirstOnLine = NO; 153 self.isLastOnLine = NO; 154 self.containsStart = NO; 155 self.containsEnd = NO; 156 self.isInFixedPosition = NO; 157 self.isHorizontal = NO; 158 159 return self; 160} 161 162- (id)copyWithZone:(NSZone *)zone 163{ 164 WebSelectionRect *copy = [[WebSelectionRect selectionRect] retain]; 165 copy.rect = self.rect; 166 copy.writingDirection = self.writingDirection; 167 copy.isLineBreak = self.isLineBreak; 168 copy.isFirstOnLine = self.isFirstOnLine; 169 copy.isLastOnLine = self.isLastOnLine; 170 copy.containsStart = self.containsStart; 171 copy.containsEnd = self.containsEnd; 172 copy.isInFixedPosition = self.isInFixedPosition; 173 copy.isHorizontal = self.isHorizontal; 174 return copy; 175} 176 177- (NSString *)description 178{ 179 return [NSString stringWithFormat:@"<WebSelectionRect: %p> : { %.1f,%.1f,%.1f,%.1f } %@%@%@%@%@%@%@%@", 180 self, 181 self.rect.origin.x, self.rect.origin.y, self.rect.size.width, self.rect.size.height, 182 self.writingDirection == WKWritingDirectionLeftToRight ? @"[LTR]" : @"[RTL]", 183 self.isLineBreak ? @" [BR]" : @"", 184 self.isFirstOnLine ? @" [FIRST]" : @"", 185 self.isLastOnLine ? @" [LAST]" : @"", 186 self.containsStart ? @" [START]" : @"", 187 self.containsEnd ? @" [END]" : @"", 188 self.isInFixedPosition ? @" [FIXED]" : @"", 189 !self.isHorizontal ? @" [VERTICAL]" : @""]; 190} 191 192@end 193 194#endif // PLATFORM(IOS) 195