Skip to content

Instantly share code, notes, and snippets.

@orklann
Created October 30, 2020 02:23
Show Gist options
  • Save orklann/5a7a4ae666368bd23406801e8951c6ad to your computer and use it in GitHub Desktop.
Save orklann/5a7a4ae666368bd23406801e8951c6ad to your computer and use it in GitHub Desktop.
PEP: GMisc: isWordBreaks(); GTextParser: makeWords
// Check if two glyphs mark a word break, function like a white space
// GMisc.m
BOOL isWordBreaks(GGlyph *a, GGlyph *b) {
if (a == nil || b == nil) {
BOOL result = NO;
//NSLog(@"Nil case cur: %@ next: %@ result: %d", [a content], [b content], result);
return result;
}
NSRect f1 = [a frame];
NSRect f2 = [b frame];
CGFloat yMinA = NSMinY(f1);
CGFloat yMinB = NSMinY(f2);
CGFloat xA = NSMaxX(f1);
CGFloat xB = NSMinX(f2);
CGFloat widthA = NSWidth(f1);
CGFloat widthB = NSWidth(f2);
CGFloat heightA = NSHeight(f1);
CGFloat heightB = NSHeight(f1);
BOOL result = NO;
CGFloat dy = fabs(yMinA - yMinB);
CGFloat heightDelta = MAX(heightA, heightB);
CGFloat percent = (dy / heightDelta);
CGFloat heightTolerance = 0.05;
if (percent <= heightTolerance) {
CGFloat dx = fabs(xA - xB);
CGFloat widthTolerance = (widthA + widthB) / 2.0;
if (dx <= widthTolerance) {
result = NO;
} else {
result = YES;
}
} else {
result = YES;
}
//NSLog(@"dy: %f cur: %@ next: %@ result: %d", dy, [a content], [b content], result);
return result;
}
// GTextParser.m
- (NSMutableArray*)makeWords{
[self makeReadOrderGlyphs];
words = [NSMutableArray array];
if ([readOrderGlyphs count] <= 0) {
return words;
}
glyphPos = 0;
GWord *currentWord = [GWord create];
GGlyph *nextGlyph = [self currentGlyph];
GGlyph *glyphAfter;
while(nextGlyph != nil) {
glyphAfter = [self peekNextGlyph];
if (isWhiteSpaceGlyph(nextGlyph) || isWordBreaks(nextGlyph, glyphAfter)) {
// Current glyph (nextGlyph) can breaks two words, and it's not a
// white space, so we add it to current word.
// Example:
// "Editing"
// "Program"
// Here the `g` in `Editing` can breaks two words although it's not
// a white space.
if (isWordBreaks(nextGlyph, glyphAfter)) {
[currentWord addGlyph:nextGlyph];
nextGlyph = [self nextGlyph];
}
// Add previous word
[words addObject:currentWord];
// Handle edge case: where more than two white spaces stick
// together. We add each white space as a single word until we
// reach a none white space
while (isWhiteSpaceGlyph(nextGlyph)) {
currentWord = [GWord create];
[currentWord addGlyph:nextGlyph];
[words addObject:currentWord];
nextGlyph = [self nextGlyph];
}
currentWord = [GWord create];
} else {
[currentWord addGlyph:nextGlyph];
nextGlyph = [self nextGlyph];
}
}
if ([[currentWord glyphs] count] > 0) {
[words addObject:currentWord];
}
//prettyLogForWords(words);
return words;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment