From 19cea3837c681232b8fdbae36fe24c7d82de3cd3 Mon Sep 17 00:00:00 2001 From: Matthias Neeracher Date: Tue, 25 Dec 2007 16:49:45 +0000 Subject: [PATCH] Refactor to VLTextLayout, with original algorithm --- Sources/VLLayout.cpp | 42 ++++++++++++++++++++++++ Sources/VLLayout.h | 23 +++++++++++++ Sources/VLSheetViewLyrics.mm | 63 +++++++++++++++++++++++++----------- 3 files changed, 109 insertions(+), 19 deletions(-) diff --git a/Sources/VLLayout.cpp b/Sources/VLLayout.cpp index b7846e5..5b3310e 100644 --- a/Sources/VLLayout.cpp +++ b/Sources/VLLayout.cpp @@ -91,3 +91,45 @@ float VLLayout::NotePosition(int measure, VLFraction at) const } return 0.0f; } + +VLFontHandler::~VLFontHandler() +{ +} + +VLTextLayout::VLTextLayout(VLFontHandler * regular, VLFontHandler * narrow) + : fRegularFont(regular), fNarrowFont(narrow) +{ +} + +void VLTextLayout::AddSyllable(const VLSyllable & syll, float x) +{ + VLLayoutSyll ls; + + static_cast(ls) = syll; + ls.fX = x; + + fSyllables.push_back(ls); +} + +typedef std::vector::iterator VLSyllIter; + +#define NARROW_SPACE "\xE2\x80\x89" + +void VLTextLayout::DrawLine(float y) +{ + VLSyllIter syll = fSyllables.begin(); + VLSyllIter end = fSyllables.end(); + + while (syll != end) { + std::string text = syll->fText; + float x = syll->fX-0.5*fRegularFont->Width(text.c_str()); + if (syll == fSyllables.begin() && syll->fKind & VLSyllable::kHasPrev) + text = "-" NARROW_SPACE + text; + if (syll->fKind & VLSyllable::kHasNext) + text += NARROW_SPACE "-"; + + fRegularFont->Draw(x, y, text.c_str()); + + ++syll; + } +} diff --git a/Sources/VLLayout.h b/Sources/VLLayout.h index 9ce72d3..4394463 100644 --- a/Sources/VLLayout.h +++ b/Sources/VLLayout.h @@ -43,6 +43,29 @@ public: float NotePosition(int measure, VLFraction at) const; }; +class VLFontHandler { +public: + virtual void Draw(float x, float y, const char * utf8Text) = 0; + virtual float Width(const char * utf8Text) = 0; + virtual ~VLFontHandler(); +}; + +struct VLLayoutSyll : public VLSyllable { + float fX; +}; + +class VLTextLayout { +public: + VLTextLayout(VLFontHandler * regular, VLFontHandler * narrow); + + void AddSyllable(const VLSyllable & syll, float x); + void DrawLine(float y); +private: + VLFontHandler * fRegularFont; + VLFontHandler * fNarrowFont; + std::vector fSyllables; +}; + // Local Variables: // mode:C++ // End: diff --git a/Sources/VLSheetViewLyrics.mm b/Sources/VLSheetViewLyrics.mm index 7dfd454..88e88ba 100644 --- a/Sources/VLSheetViewLyrics.mm +++ b/Sources/VLSheetViewLyrics.mm @@ -100,17 +100,50 @@ @end +class VLCocoaFontHandler : public VLFontHandler { +public: + VLCocoaFontHandler(NSString * name, float size); + + virtual void Draw(float x, float y, const char * utf8Text); + virtual float Width(const char * utf8Text); +private: + NSDictionary * fTextAttr; +}; + +VLCocoaFontHandler::VLCocoaFontHandler(NSString * name, float size) +{ + NSFont * font = [NSFont fontWithName:name size:size]; + + fTextAttr = + [[NSDictionary alloc] initWithObjectsAndKeys: + font, NSFontAttributeName, nil]; +} + +void VLCocoaFontHandler::Draw(float x, float y, const char * utf8Text) +{ + NSString * t = [NSString stringWithUTF8String:utf8Text]; + [t drawAtPoint:NSMakePoint(x,y) withAttributes:fTextAttr]; +} + +float VLCocoaFontHandler::Width(const char * utf8Text) +{ + NSString * t = [NSString stringWithUTF8String:utf8Text]; + NSSize sz= [t sizeWithAttributes:fTextAttr]; + + return sz.width; +} + @implementation VLSheetView (Lyrics) - (void) drawLyricsForSystem:(int)system stanza:(size_t)stanza { - static NSDictionary * sLyricsFont = nil; - if (!sLyricsFont) - sLyricsFont = - [[NSDictionary alloc] initWithObjectsAndKeys: - [NSFont fontWithName: @"Helvetica" size: 12], - NSFontAttributeName, - nil]; + static VLFontHandler * sRegularFont = nil; + static VLFontHandler * sNarrowFont = nil; + if (!sRegularFont) { + sRegularFont = new VLCocoaFontHandler(@"Arial", 12.0f); + sNarrowFont = new VLCocoaFontHandler(@"ArialNarrow", 12.0f); + } + VLTextLayout text(sRegularFont, sNarrowFont); const VLSong * song = [self song]; const float kSystemY = [self systemY:system]; @@ -136,22 +169,14 @@ ) { ; } else { - NSString * syll = - [NSString stringWithUTF8String: - note->fLyrics[stanza-1].fText.c_str()]; - NSSize sz = - [syll sizeWithAttributes:sLyricsFont]; - NSPoint syllLoc = - NSMakePoint([self noteXInMeasure:measIdx at:at] - - 0.5f*sz.width, - kSystemY+kLyricsY-stanza*kLyricsH); - if (note->fLyrics[stanza-1].fKind & VLSyllable::kHasNext) - syll = [syll stringByAppendingString:@" -"]; - [syll drawAtPoint:syllLoc withAttributes:sLyricsFont]; + text.AddSyllable(note->fLyrics[stanza-1], + [self noteXInMeasure:measIdx at:at]); } at += note->fDuration; } } + + text.DrawLine(kSystemY+kLyricsY-stanza*kLyricsH); } - (void) editLyrics