5

私は現在、Windows Phone Seven用のeBookリーダーを作成しており、Kindleリーダーのようにスタイルを設定しようとしています。そのためには、本をページに分割する必要があります。可変フォントサイズを追加すると、これはさらに複雑になります。

現時点でこれを行うには、コンテナよりも高くなるまで、テキストブロックに一度に1つの単語を追加します。ご想像のとおり、120,000語を超えるドキュメントでは、これには許容できない時間がかかります。

実際にレンダリングしなくても、テキストが境界を超える(論理的にページに分割される)時期を見つける方法はありますか?そうすれば、バックグラウンドスレッドで実行できるので、ユーザーはその間も読み続けることができます。

これまでのところ、私が思いついた唯一のアイデアは、テキストブロックがその境界を決定する方法を見つけることです(メジャーコールで?)が、リフレクターが何も表示しなかったため、そのコードを見つける方法がわかりません。

前もって感謝します!

4

4 に答える 4

4

私が見ることができることから、Kindleアプリはあなたが提案したものと同様のアルゴリズムを使用しているように見えます。ご了承ください:

  • 通常、本全体の%の位置が表示されます。合計ページ数は表示されません。

  • フォントサイズを変更しても、ページの最初の単語は同じままです(つまり、%の由来です)。したがって、Kindleアプリは、ページの最初の単語が同じままであると仮定して、1ページ分の再ページングを実行します。

  • フォントサイズを変更してから最初のページにスクロールして戻ると、実際には不連続性があります。最初のページを埋めるために、コンテンツが再び前方にプルされます。

これに基づいて、本全体を索引付けしないことをお勧めします。代わりに、ある種の「位置」に基づいて現在のページに集中するだけです(たとえば、文字数-パーセンテージで表示されます)。バックグラウンドスレッドで何かを行う必要がある場合は、スクロールの応答性を高めるために、次のページ(および前のページ)を確認してください。

さらにエクスペリエンスを最適化するために、現在のアルゴリズムに加えることができるいくつかの変更を試すことができます。

  • アルゴリズムの開始点と検索増分を変えてみてください。1つの単語から始めて、一度に1つの単語だけを追加する必要はありません。

  • ほとんどの本がASCIIであると仮定して、一般的な文字の幅をキャッシュしてから、テキストブロックの幅を自分で計算してみてください。

<Run>それ以外にも、TextBlock内でブロックを使用してみたいと思います。TextBlock内の各Runの相対位置を取得できる可能性がありますが、まだこれを行うことはできません。

于 2011-02-27T18:41:40.413 に答える
3

個々のテキストボックスのフォントサイズを調整するのと同じようなことをします(すべてが収まるようにするため)。基本的に、コードでTextBlockを作成し、すべてのプロパティを設定して、ActualWidthプロパティとActualHeightプロパティを確認します。問題を解決するための疑似コードを次に示します。

public static String PageText(TextBlock txtPage, String BookText)
{
    TextBlock t = new TextBlock();
    t.FontFamily = txtPage.FontFamily;
    t.FontStyle = txtPage.FontStyle;
    t.FontWeight = txtPage.FontWeight;
    t.FontSize = txtPage.FontSize;
    t.Text = BookText;

    Size Actual = new Size();
    Actual.Width = t.ActualWidth;
    Actual.Height = t.ActualHeight;

    if(Actual.Height <= txtPage.ActualHeight)
        return BookText;

    Double hRatio = txtPage.ActualHeight / Actual.Height;
    return s.Substring((int)((s.Length - 1) * hRatio));
}

上記はテストされていないコードですが、うまくいけば始めることができます。基本的に、テキストがボックスに収まるかどうかを確認します。収まる場合は、問題ありません。そうでない場合は、テキストの何パーセントが収まるかを調べて返します。これは単語の区切りを考慮に入れておらず、完全に一致するわけではないかもしれませんが、あなたを近づけるはずです。

このコードを変更して、実際の部分文字列ではなく長さを返し、それをページサイズとして使用することができます。コード(表示なし)でテキストブロックを作成すると、実際にはかなりうまく機能します(いくつかのテーブルビューでは、目立った遅れはありません)。この関数に120,000語すべてを送信するわけではありませんが、ある種の妥当なサブセットを送信します。

理想的な長さになったら、正規表現を使用して本をページに分割できます。正規表現のこのサイトには、特定の長さの後に単語の境界を破る例があります。


もう1つのオプションは、潜在的なフォントサイズごとに事前にページサイズを計算することです(そしてswitchステートメントでハードコーディングします)。これは、任意のフォントと任意のサイズの組み合わせを許可している場合は簡単に気が狂う可能性があり、混合フォント/サイズを許可している場合はひどいものになりますが、非常にうまく機能します。ほとんどの場合、読み取り可能なサイズの特定の範囲と、ほんの数個のフォントがあります。これらの組み合わせごとにページのテキストの長さを計算するテストアプリを作成することはそれほど難しくなく、プログラマーとして正しく「感じ」なくても、おそらくあなたの生活を楽にするでしょう:)

于 2011-03-01T14:28:19.373 に答える
1

「ページ付けの原則」と呼ばれるMicrosoftからのこの例への参照は見つかりませんでした。

WindowsPhoneで実行されている興味深いサンプルコードがいくつかあります。

http://msdn.microsoft.com/en-us/magazine/hh205757.aspx

また、Windows Phoneのページ遷移に関するこの記事や、E-Bookプロジェクトの最後の仕上げに関するこの記事も参照できます。

コードはダウンロード可能です:http ://archive.msdn.microsoft.com/mag201111UIFrontiers/Release/ProjectReleases.aspx?ReleaseId = 5776

于 2013-09-08T22:05:34.220 に答える
0

textBlock内でAFAIKで使用されるFormattedTextクラスを照会できます。これは、レンダリングの準備としてテキストをフォーマットするために使用されるクラスであるため、これは利用可能な最も低レベルのクラスであり、高速である必要があります。

于 2011-02-27T04:09:26.187 に答える