mirror of
https://github.com/macvim-dev/macvim.git
synced 2026-06-11 15:37:29 +02:00
Added custom typesetter (better wide-font support, can typeset proportional fonts)
git-svn-id: http://macvim.googlecode.com/svn/trunk@105 96c4425d-ca35-0410-94e5-3396d5c13a8f
This commit is contained in:
@@ -58,5 +58,6 @@
|
||||
- (BOOL)resizeToFitSize:(NSSize)size;
|
||||
- (NSSize)fitToSize:(NSSize)size;
|
||||
- (NSSize)fitToSize:(NSSize)size rows:(int *)rows columns:(int *)columns;
|
||||
- (float)cellWidth;
|
||||
|
||||
@end
|
||||
|
||||
+5
-6
@@ -29,7 +29,6 @@
|
||||
@interface MMTextStorage (Private)
|
||||
- (void)doSetMaxRows:(int)rows columns:(int)cols;
|
||||
- (void)lazyResize;
|
||||
- (float)cellWidth;
|
||||
- (float)widthOfEmptyRow;
|
||||
@end
|
||||
|
||||
@@ -509,6 +508,11 @@
|
||||
return fitSize;
|
||||
}
|
||||
|
||||
- (float)cellWidth
|
||||
{
|
||||
return [font widthOfString:@"W"];
|
||||
}
|
||||
|
||||
@end // MMTextStorage
|
||||
|
||||
|
||||
@@ -568,11 +572,6 @@
|
||||
actualRows = rows; actualColumns = cols;
|
||||
}
|
||||
|
||||
- (float)cellWidth
|
||||
{
|
||||
return [font widthOfString:@"W"];
|
||||
}
|
||||
|
||||
- (float)widthOfEmptyRow
|
||||
{
|
||||
return [font widthOfString:[emptyRowString string]];
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/* vi:set ts=8 sts=4 sw=4 ft=objc:
|
||||
*
|
||||
* VIM - Vi IMproved by Bram Moolenaar
|
||||
* MacVim GUI port by Bjorn Winckler
|
||||
*
|
||||
* Do ":help uganda" in Vim to read copying and usage conditions.
|
||||
* Do ":help credits" in Vim to see a list of people who contributed.
|
||||
* See README.txt for an overview of the Vim source code.
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
|
||||
@interface MMTypesetter : NSTypesetter {
|
||||
}
|
||||
|
||||
- (void)layoutGlyphsInLayoutManager:(NSLayoutManager *)lm
|
||||
startingAtGlyphIndex:(unsigned)startGlyphIdx
|
||||
maxNumberOfLineFragments:(unsigned)maxNumLines
|
||||
nextGlyphIndex:(unsigned *)nextGlyph;
|
||||
|
||||
@end
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
/* vi:set ts=8 sts=4 sw=4 ft=objc:
|
||||
*
|
||||
* VIM - Vi IMproved by Bram Moolenaar
|
||||
* MacVim GUI port by Bjorn Winckler
|
||||
*
|
||||
* Do ":help uganda" in Vim to read copying and usage conditions.
|
||||
* Do ":help credits" in Vim to see a list of people who contributed.
|
||||
* See README.txt for an overview of the Vim source code.
|
||||
*/
|
||||
|
||||
#import "MMTypesetter.h"
|
||||
#import "MMTextStorage.h"
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
@interface MMTypesetter (Private)
|
||||
- (NSCharacterSet *)hiddenCharSet;
|
||||
@end
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@implementation MMTypesetter
|
||||
|
||||
//
|
||||
// Layout glyphs so that each glyph takes up exactly one cell.
|
||||
//
|
||||
// The width of a cell is determined by [MMTextStorage cellWidth] (which
|
||||
// typically sets one cell to equal the width of 'W' in the current font), and
|
||||
// the height of a cell is given by the default line height for the current
|
||||
// font.
|
||||
//
|
||||
// It is assumed that the text storage is set up so that each wide character is
|
||||
// followed by a 'zero-width space' character (Unicode 0x200b); these are not
|
||||
// rendered. If a wide character is not followed by a zero-width space, then
|
||||
// the next character will render on top of it.
|
||||
//
|
||||
- (void)layoutGlyphsInLayoutManager:(NSLayoutManager *)lm
|
||||
startingAtGlyphIndex:(unsigned)startGlyphIdx
|
||||
maxNumberOfLineFragments:(unsigned)maxNumLines
|
||||
nextGlyphIndex:(unsigned *)nextGlyph
|
||||
{
|
||||
// TODO: Check that it really is an MMTextStorage.
|
||||
MMTextStorage *ts = (MMTextStorage*)[lm textStorage];
|
||||
NSTextView *tv = [lm firstTextView];
|
||||
NSTextContainer *tc = [tv textContainer];
|
||||
NSFont *font = [ts font];
|
||||
NSString *text = [ts string];
|
||||
unsigned textLen = [text length];
|
||||
float cellWidth = [ts cellWidth];
|
||||
float cellHeight = [lm defaultLineHeightForFont:font];
|
||||
float baseline = [font descender];
|
||||
|
||||
if (!(ts && tv && tc && font && text && textLen))
|
||||
return;
|
||||
|
||||
unsigned startCharIdx = [lm characterIndexForGlyphAtIndex:startGlyphIdx];
|
||||
unsigned i, numberOfLines = 0, firstLine = 0;
|
||||
NSRange firstLineRange = { 0, 0 };
|
||||
|
||||
// Find first line and its range, and count the number of lines.
|
||||
for (i = 0; i < textLen; numberOfLines++) {
|
||||
NSRange lineRange = [text lineRangeForRange:NSMakeRange(i, 0)];
|
||||
if (NSLocationInRange(startCharIdx, lineRange)) {
|
||||
firstLine = numberOfLines;
|
||||
firstLineRange = lineRange;
|
||||
}
|
||||
|
||||
i = NSMaxRange(lineRange);
|
||||
}
|
||||
|
||||
// Perform line fragment generation one line at a time.
|
||||
NSRange lineRange = firstLineRange;
|
||||
unsigned endGlyphIdx = startGlyphIdx;
|
||||
for (i = 0; i < maxNumLines && lineRange.length; ++i) {
|
||||
NSRange glyphRange = [lm glyphRangeForCharacterRange:lineRange
|
||||
actualCharacterRange:nil];
|
||||
NSRect lineRect = { 0, (firstLine+i)*cellHeight,
|
||||
cellWidth*(lineRange.length-1), cellHeight };
|
||||
unsigned endLineIdx = NSMaxRange(lineRange);
|
||||
NSPoint glyphPt = { 0, cellHeight+baseline };
|
||||
unsigned j;
|
||||
|
||||
endGlyphIdx = NSMaxRange(glyphRange);
|
||||
|
||||
[lm setTextContainer:tc forGlyphRange:glyphRange];
|
||||
[lm setLineFragmentRect:lineRect forGlyphRange:glyphRange
|
||||
usedRect:lineRect];
|
||||
//[lm setLocation:glyphPt forStartOfGlyphRange:glyphRange];
|
||||
|
||||
// Position each glyph individually to ensure they take up exactly one
|
||||
// cell.
|
||||
for (j = glyphRange.location; j < endGlyphIdx; ++j) {
|
||||
[lm setLocation:glyphPt forStartOfGlyphRange:NSMakeRange(j, 1)];
|
||||
glyphPt.x += cellWidth;
|
||||
}
|
||||
|
||||
// Hide non-zero space characters (there is one after every wide
|
||||
// character).
|
||||
for (j = lineRange.location; j < endLineIdx; ++j) {
|
||||
if ([text characterAtIndex:j] == 0x200b) {
|
||||
NSRange range = { j, 1 };
|
||||
range = [lm glyphRangeForCharacterRange:range
|
||||
actualCharacterRange:nil];
|
||||
[lm setNotShownAttribute:YES forGlyphAtIndex:range.location];
|
||||
}
|
||||
}
|
||||
|
||||
lineRange = [text lineRangeForRange:NSMakeRange(endLineIdx, 0)];
|
||||
}
|
||||
|
||||
if (nextGlyph)
|
||||
*nextGlyph = endGlyphIdx;
|
||||
}
|
||||
|
||||
@end // MMTypesetter
|
||||
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
@implementation MMTypesetter (Private)
|
||||
|
||||
- (NSCharacterSet *)hiddenCharSet
|
||||
{
|
||||
static NSCharacterSet *hiddenCharSet = nil;
|
||||
|
||||
if (!hiddenCharSet) {
|
||||
NSString *string = [NSString stringWithFormat:@"%C\n", 0x200b];
|
||||
hiddenCharSet = [NSCharacterSet
|
||||
characterSetWithCharactersInString:string];
|
||||
[hiddenCharSet retain];
|
||||
}
|
||||
|
||||
return hiddenCharSet;
|
||||
}
|
||||
|
||||
@end // MMTypesetter (Private)
|
||||
#endif
|
||||
@@ -8,6 +8,8 @@
|
||||
* See README.txt for an overview of the Vim source code.
|
||||
*/
|
||||
|
||||
#define MM_USE_CUSTOM_TYPESETTER 1
|
||||
|
||||
#import "MMWindowController.h"
|
||||
#import <PSMTabBarControl.h>
|
||||
#import "MMTextView.h"
|
||||
@@ -16,6 +18,10 @@
|
||||
#import "MacVim.h"
|
||||
#import "MMAppController.h"
|
||||
|
||||
#if MM_USE_CUSTOM_TYPESETTER
|
||||
# import "MMTypesetter.h"
|
||||
#endif
|
||||
|
||||
|
||||
// Scroller type; these must match SBAR_* in gui.h
|
||||
enum {
|
||||
@@ -107,6 +113,12 @@ NSMutableArray *buildMenuAddress(NSMenu *menu)
|
||||
NSTextContainer *tc = [[NSTextContainer alloc] initWithContainerSize:
|
||||
NSMakeSize(1.0e7,1.0e7)];
|
||||
|
||||
#if MM_USE_CUSTOM_TYPESETTER
|
||||
MMTypesetter *typesetter = [[MMTypesetter alloc] init];
|
||||
[lm setTypesetter:typesetter];
|
||||
[typesetter release];
|
||||
#endif
|
||||
|
||||
[tc setWidthTracksTextView:NO];
|
||||
[tc setHeightTracksTextView:NO];
|
||||
[tc setLineFragmentPadding:0];
|
||||
|
||||
Reference in New Issue
Block a user