[IMPRESSION] Images d' AttributedString s'imprimant mal dans un Header

ClicCoolClicCool Membre
janvier 2008 modifié dans API AppKit #1
Bonjour,

Je ne parviens pas du tout à  élucider ce mystère.

Je souhaite imprimer des Headers et Footers à  partir de l'AttributedString récupérées de NSTextView nommés header et footer (permettant justement à  l'utilisateur de définir ceux-ci).

Pour celà  l'utilise:
-(void)drawPageBorderWithSize:(NSSize)borderSize de NSView
où, entre un lockFocus et un unLockFocus, j'envoie:
if (header) {<br />			NSAttributedString * headerText = (NSAttributedString*) [header textStorage];<br />			[headerText drawInRect: NSMakeRect([pInfo leftMargin], maxTop-[self hauteurHeader], borderSize.width - [pInfo leftMargin] - [pInfo rightMargin],[self hauteurHeader])];<br />		}


Et alors que pour un grand document tout marche à  merveille, dès que le document à  imprimer fait moins de 1 page + 7 lignes (précisément !!) les images de l'AttributedString ne s'impriment plus mais son texte oui !? ???
Il y a comme un place holder à  la place de l'image mais pas l'image, le texte du Header lui s'imprime toujours avec sa mise en forme et à  la bonne place.
Et idem si, indépendament du texte à  imprimer, je force la View imprimée en corps de texte à  une taille supérieure ou inférieure à  1 page + 7 lignes ???

Je ne vois pas le lien entre la taille de la View imprimée dans le corps de la page et l'impression des images du Header qui se fait dans la marge. Et pourtant il y en a un surement !

Je précise que le Footer, lui, s'imprime toujours bien sans problème quel que soit son contenu.


Peut-être qu'en image ce sera plus "parlant": exemples de résultats avec le même Header

Réponses

  • ClicCoolClicCool Membre
    16:50 modifié #2
    De bizarre en bizarre ...

    le drawInRect de NSImageRep fonctionne bien dans les headers contrairement au drawInRect des AttributedStrings
    donc, si au lieu d'imprimer une AttributedString dans mon Header, j'imprime direct une image ça marche nickel.
    Faudrait maintenant que je découvre comment transformer à  la volée mon AttributedString en Image. C'est faisable ?

    Du côté de l'impression des Headers et footer sur 10.4 + j'ai fini par trouver le chaà®non manquant dans ma compréhension des chose ICI (Notes specific to MacOS X 10.4: Automatic page headers/footers in printouts (Added since WWDC) )
    C'est fou comme, pour ce qui est des impressions, les informations sont disséminées.
    (et sur la dev-list ceux qui ont posé des questions à  ce sujet sont ignorés ou rembarrés façon "c'est très clair, on en a déjà  parlé" etc...)

    Bref j'ai enfin compris au mieux les mécanismes et comment tirer parti des nouvelles méthodes de NSView:
    - (NSAttributedString *)pageHeader;
    - (NSAttributedString *)pageFooter;

    Super génial! ce n'est plus moi qui doit me charger directement de l'impression de mes AttributedStrings dans le Header !
    J'ai qu'à  transmettre mes attributedString à  l'appel de ces fonctions. (et ne PAS implémenter de drawPageBorderWithSize ou alors d'y appeler super...)

    Mais voilà  ! ... même quand je laisse faire l'APPKit le résultat est strictement le même !! (sauf qu'en plus c'est mal cadré et tronqué sur toutes les pages ! mais ça doit pouvoir se paramétrer ...)
    ET avec une bizarrerie de plus qui me laisse pantois: Il m'imprime ce que je renvoie avec pageHeader dans le pied de page et ce que je renvoie avec pageFooter dans l'entête !!! ???
    (et même les entêtes et pieds par défaut sont inversés ! faut que je revois mon printInfo sans doutes ? ...)

    Je me demande si je devrais pas poster ça à  la dev-list ? (pas trop envie de me faire rembarrer non plus ...  B) )


  • AliGatorAliGator Membre, Modérateur
    16:50 modifié #3
    dans 1201599464:

    Faudrait maintenant que je découvre comment transformer à  la volée mon AttributedString en Image. C'est faisable ?
    Je dis ça comme ça, mais si tu crées une NSImage, que tu fais un lockFocus dessus, puis un draw de ton attributedString, et un unlockFocus, tu l'as pas, ton attributedString convertie en image ??
  • ClicCoolClicCool Membre
    16:50 modifié #4
    dans 1201613439:
    Je dis ça comme ça, mais si tu crées une NSImage, que tu fais un lockFocus dessus, puis un draw de ton attributedString, et un unlockFocus, tu l'as pas, ton attributedString convertie en image ??

    Je me demandais justement, dans ma voiture, si une telle chose était faisable.
    (j'avais un doute surtout pour une vue offScreen car j'ai encore jamais manipulé le focus)

    Merci ++ on cherche encore mieux quand on sait qu'on va trouver :)
  • AliGatorAliGator Membre, Modérateur
    16:50 modifié #5
    dans 1201614944:

    dans 1201613439:
    Je dis ça comme ça, mais si tu crées une NSImage, que tu fais un lockFocus dessus, puis un draw de ton attributedString, et un unlockFocus, tu l'as pas, ton attributedString convertie en image ??

    Je me demandais justement, dans ma voiture, si une telle chose était faisable.
    (j'avais un doute surtout pour une vue offScreen car j'ai encore jamais manipulé le focus)

    Merci ++ on cherche encore mieux quand on sait qu'on va trouver :)
    Ouais enfin c'est la journée des gens qui postent du code alors qu'ils sont au taf sur leur PC sans pouvoir tester :)
    Donc je garantis pas que ça marche non plus. C'est juste que si tu veux faire ça c'est comme ça que j'aurais fait.
  • ClicCoolClicCool Membre
    16:50 modifié #6
    Y'a pas de raisons que ça marche pas Mon môche PC m'a trouvé ce genre d'exemple de code sur ADC

    NSImage* anImage = [[NSImage alloc] initWithSize:NSMakeSize(100.0,&nbsp; 100.0)]; <br />[anImage lockFocus];&nbsp;  <br />// Do your drawing here... <br />
    

    Donc on peut "locker' le focus sur une image non seulement offScreen mais fraichement créé...  :)
    J'ai hâte d'essayer en tous cas.

    Et de toutes façons t'inquiètes pas pour le résultat, je finirais bien par trouver (enfin j'espère )
    Et je n'ai jamais autant progressé qu'en affrontant des diffucultés ;)

    Et enfin si j'y arrive pas comme ça, je penserais bien fort à  Ferninde et essaierais de Binder le data d'une Image sur un NSMutableData lui même Bindé sur mon TextView ! c'est tellement fou que ça pourrait marcher  !? ! :P
  • ClicCoolClicCool Membre
    16:50 modifié #7
    Non seulement on peut "locker" sur une image offScreen mais il semble que de toutes façons un lock envoyé à  une image est en fait systématiquement appilqué à  une représentation en offScreen !

    Drawing to an image creates an NSCachedImageRep object or uses an existing cached image representation, if one exists. Even when you use the lockFocusOnRepresentation: method to lock onto a specific image representation, you do not lock onto the representation itself. Instead, you lock onto the cached offscreen window associated with that image representation.
  • ClicCoolClicCool Membre
    16:50 modifié #8
    Bonne Nouvelle, le truc d'Ali marche :)

    L'image résultante peut ainsi remplacer l'impression directe mais incomplète de l'AttribrutedString elle même.



    Par contre l'image ainsi créée est de bien piètre qualité.
    J'imagine que "l'impression" sur une view supposée affichable sur un moniteur n'a pas la même définition que pour une imprimante laser, mais là  c'est encore pire que d'imprimer une simple capture d'écran... :(

    J'ai essayé d'utiliser l'option NSStringDrawingDisableScreenFontSubstitution de drawWithRect: option: des AttributedString mais sans grande amélioration.
    J'ai essayé aussi de crée une image 32 fois plus grande en y dessinant 32 fois plus gros, avec une amélioration plus sensible mais très insuffisante, et un ralentissement sensible de l'appli au lancement de l'impression.
    J'ai même essayé une image 100 fois plus grande mais là  ça ralenti plus ça bloque l'impression. Mon ordi prenant sans doutes alors le header pour un oeuf de Pâques s'est plein de ne pas pouvoir le "cacher" ! ("Can't cache image")



  • 16:50 modifié #9
    Tu n'imagines pas mal, une image créée offscreen a par défaut une résolution de 72dpi. Si c'est pire qu'une capture d'écran, il y a deux raisons:
    - soit tu dessines sur fond coloré: l'algo de lissage pour écran n'est pas adapté à  l'impression: il n'utilise pas les pixels comme unité de base, mais les sous-pixels, le résultat n'est donc probant que sur un écran LCD avec des sous-pixels verticaux.
    - soit tu dessines sur fond transparent et dans ce cas l'algo avec les sous-pixels n'est pas utilisé, c'est un autre dont le rendu est assez horrible pour les petites tailles de caractères (regarde le rendu texte dans Pages si tu veux te faire une idée).

    Donc le mieux pour "convertir" une NSAttributedString en image serait d'augmenter la résolution de la représentation.
  • ClicCoolClicCool Membre
    janvier 2008 modifié #10
    Bonsoir Renaud :)

    dans 1201644351:
    - soit tu dessines sur fond coloré: l'algo de lissage pour écran n'est pas adapté à  l'impression: il n'utilise pas les pixels comme unité de base, mais les sous-pixels, le résultat n'est donc probant que sur un écran LCD avec des sous-pixels verticaux.
    - soit tu dessines sur fond transparent et dans ce cas l'algo avec les sous-pixels n'est pas utilisé, c'est un autre dont le rendu est assez horrible pour les petites tailles de caractères (regarde le rendu texte dans Pages si tu veux te faire une idée).


    Pour être hônette je suis pas sûr de savoir sur quoi je dessine  :-\\
    C'est juste dans une NSView à  peine initialisée avec intitWithSize...

    dans 1201644351:

    Donc le mieux pour "convertir" une NSAttributedString en image serait d'augmenter la résolution de la représentation.

    Merci.
    C'est un peu ce que j'essaies de faire d'abord en créant une image bien plus grande.
    Et là , je suis en train d'essayer de dessiner cette image directement pendant l'impression c'est à  dire à  chaque page (pas glop pas glop) mais en espérant du coup hériter du contexte de l'impression en cours, histoire de voir.

    Mais je crois qu'il va falloir que je me penche un peu sur la classe NSGraphicsContext ...


    [EDIT] aucun résultat en créant l'image avec l'impression de chaque page :(
  • BruBru Membre
    16:50 modifié #11
    Je te conseille de passer par PDF pour créer les images des entêtes/pieds de page.

    D'abord, tu créés un custom-view chargé de dessiner ton entête (ou pied de page).
    Pour le moment tu n'as besoin que tu drawRect: dans lequel tu dessines tes images et tes NSAttributedString.

    Ensuite, le but du jeu est de créer un NSPDFImageRep à  partir de ce custom-view.

    Enfin, il ne te resteras plus qu'à  dessiner ce NSPDFImageRep dans ta view à  imprimer.

    <br />{<br />    NSPDFImageRep *pdf;<br />    EnteteView *entete;<br /><br />    entete=[[EnteteView alloc] initWithFrame:NSMakeRect(0, 0, 300, 100)];<br />    pdf=[[NSPDFImageRep alloc] initWithData:[entete dataWithPDFInsideRect:[entete bounds]]];<br />    [entete release];<br />    [pdf drawAtPoint:unpoint];<br />    [pdf release];<br />}<br />
    


    L'avantage de PDF est d'être indépendant de la résolution (les textes dessinés restent vectoriels par exemple).

    .
  • ClicCoolClicCool Membre
    16:50 modifié #12

    IMPECCABLE MERCI BRU  <3 <br />
    Et J'en étais encore loin au bout du compte !
    J'avais pas remarqué qu'il fallait aller voir les sous classes de NSImageRep -> je vais devoir ré-installer Apkido)

    En plus c'est très facile et souple à  mettre en oeuvre ça marche avec une vue un peu complexe et ça marche même en passant directement les paramètres d'une TexView. Et chaque fois avec un résultat impeccable.  :brule:
  • BruBru Membre
    16:50 modifié #13
    dans 1201650283:

    IMPECCABLE MERCI BRU  <3 <br />


    C'est bon ?
    J'ai perdu mon statut de débutant ?

    .
  • ClicCoolClicCool Membre
    16:50 modifié #14
    dans 1201686466:

    dans 1201650283:

    IMPECCABLE MERCI BRU  <3 <br />


    C'est bon ?
    J'ai perdu mon statut de débutant ?

    .


    C'est en bonne voie en tous cas  :o

    Mais si "=" au lieu de "==" est une erreur de débutant, à  vrai dire, un débutant écrit if (maVariable == YES) et je suis sur que toi t'écris plutôt if (YES == maVariable) par sécurité. Mais ne me dit pas qu'il t'arrives jamais de te chopper une erreur à  la "invalid lValue in assignement" de temps à  autres ? non ? jamais ?

    Plus sérieusement encore, je ne me permettrais jamais de te taquiner la dessus s'il ta maitrise du code n'était pas établie de telle sorte qu'aucune ambiguité soit possible.

    Et encore plus sérieusement (si si, c'est possible) quel plaisir de retrouver ce site, son ambiance, ses membres et même les "débutants" qui usent et abusent des smiley (y'avait longtemps celle là  non ?)

    Bon, tu me pardonnes ? hein ? dis ?







    P.S.: Stp tu peux pas remettre ton ancien avatar ?
    Je sais pas pourquoi mais celui ci a comme l'air de me viser.
    Je crois même y distinguer comme une volute de fumée sortir du bout de tes doights  :o
Connectez-vous ou Inscrivez-vous pour répondre.