ReactOS  0.4.13-dev-257-gfabbd7c
richole.c
Go to the documentation of this file.
1 /*
2  * RichEdit GUIDs and OLE interface
3  *
4  * Copyright 2004 by Krzysztof Foltman
5  * Copyright 2004 Aric Stewart
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21 
22 #include <stdarg.h>
23 
24 #define NONAMELESSUNION
25 #define COBJMACROS
26 
27 #include "windef.h"
28 #include "winbase.h"
29 #include "wingdi.h"
30 #include "winuser.h"
31 #include "ole2.h"
32 #include "richole.h"
33 #include "editor.h"
34 #include "richedit.h"
35 #include "tom.h"
36 #include "wine/debug.h"
37 
39 
40 /* there is no way to be consistent across different sets of headers - mingw, Wine, Win32 SDK*/
41 
42 #include "initguid.h"
43 
44 DEFINE_GUID(LIBID_tom, 0x8cc497c9, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
45 DEFINE_GUID(IID_ITextServices, 0x8d33f740, 0xcf58, 0x11ce, 0xa8, 0x9d, 0x00, 0xaa, 0x00, 0x6c, 0xad, 0xc5);
46 DEFINE_GUID(IID_ITextHost, 0x13e670f4,0x1a5a,0x11cf,0xab,0xeb,0x00,0xaa,0x00,0xb6,0x5e,0xa1);
47 DEFINE_GUID(IID_ITextHost2, 0x13e670f5,0x1a5a,0x11cf,0xab,0xeb,0x00,0xaa,0x00,0xb6,0x5e,0xa1);
48 DEFINE_GUID(IID_ITextDocument, 0x8cc497c0, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
49 DEFINE_GUID(IID_ITextDocument2Old, 0x01c25500, 0x4268, 0x11d1, 0x88, 0x3a, 0x3c, 0x8b, 0x00, 0xc1, 0x00, 0x00);
50 DEFINE_GUID(IID_ITextRange, 0x8cc497c2, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
51 DEFINE_GUID(IID_ITextSelection, 0x8cc497c1, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
52 DEFINE_GUID(IID_ITextFont, 0x8cc497c3, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
53 DEFINE_GUID(IID_ITextPara, 0x8cc497c4, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d);
54 
55 static ITypeLib *typelib;
56 
57 enum tid_t {
65 };
66 
67 static const IID * const tid_ids[] =
68 {
69  &IID_NULL,
70  &IID_ITextDocument,
71  &IID_ITextRange,
72  &IID_ITextSelection,
73  &IID_ITextFont,
74  &IID_ITextPara,
75 };
77 
78 static HRESULT load_typelib(void)
79 {
80  ITypeLib *tl;
81  HRESULT hr;
82 
83  hr = LoadRegTypeLib(&LIBID_tom, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl);
84  if (FAILED(hr)) {
85  ERR("LoadRegTypeLib failed: %08x\n", hr);
86  return hr;
87  }
88 
90  ITypeLib_Release(tl);
91  return hr;
92 }
93 
94 void release_typelib(void)
95 {
96  unsigned i;
97 
98  if (!typelib)
99  return;
100 
101  for (i = 0; i < ARRAY_SIZE(typeinfos); i++)
102  if (typeinfos[i])
103  ITypeInfo_Release(typeinfos[i]);
104 
105  ITypeLib_Release(typelib);
106 }
107 
109 {
110  HRESULT hr;
111 
112  if (!typelib)
113  hr = load_typelib();
114  if (!typelib)
115  return hr;
116 
117  if (!typeinfos[tid])
118  {
119  ITypeInfo *ti;
120 
121  hr = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
122  if (FAILED(hr))
123  {
124  ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hr);
125  return hr;
126  }
127 
129  ITypeInfo_Release(ti);
130  }
131 
132  *typeinfo = typeinfos[tid];
133  return S_OK;
134 }
135 
136 /* private IID used to get back IRichEditOleImpl pointer */
137 DEFINE_GUID(IID_Igetrichole, 0xe3ce5c7a, 0x8247, 0x4622, 0x81, 0xad, 0x11, 0x81, 0x02, 0xaa, 0x01, 0x30);
138 
142 
170 };
171 
172 static const DWORD textfont_prop_masks[][2] = {
174  { CFM_ANIMATION },
176  { CFM_BOLD, CFE_BOLD },
177  { CFM_EMBOSS, CFE_EMBOSS },
179  { CFM_HIDDEN, CFE_HIDDEN },
181  { CFM_ITALIC, CFE_ITALIC },
182  { CFM_KERNING },
183  { CFM_LCID },
184  { CFM_FACE },
186  { CFM_OFFSET },
188  { CFM_SHADOW, CFE_SHADOW },
189  { CFM_SIZE },
191  { CFM_SPACING },
196  { CFM_WEIGHT }
197 };
198 
199 typedef union {
204 
207 };
208 
209 typedef struct IRichEditOleImpl {
215 
218 
219  struct list rangelist;
222 
223 struct reole_child {
224  struct list entry;
226 };
227 
233 };
234 
238 
240 };
241 
242 typedef struct ITextFontImpl {
245 
250 } ITextFontImpl;
251 
252 typedef struct ITextParaImpl {
255 
257 } ITextParaImpl;
258 
264 };
265 
267 {
268  return CONTAINING_RECORD(iface, IRichEditOleImpl, IRichEditOle_iface);
269 }
270 
272 {
273  return CONTAINING_RECORD(iface, IRichEditOleImpl, ITextDocument2Old_iface);
274 }
275 
277 {
278  return CONTAINING_RECORD(iface, IRichEditOleImpl, IUnknown_inner);
279 }
280 
282 {
283  return CONTAINING_RECORD(iface, IOleClientSiteImpl, IOleInPlaceSite_iface);
284 }
285 
287 {
288  return CONTAINING_RECORD(iface, ITextRangeImpl, ITextRange_iface);
289 }
290 
292 {
293  return CONTAINING_RECORD(iface, ITextSelectionImpl, ITextSelection_iface);
294 }
295 
297 {
298  return CONTAINING_RECORD(iface, ITextFontImpl, ITextFont_iface);
299 }
300 
302 {
303  return CONTAINING_RECORD(iface, ITextParaImpl, ITextPara_iface);
304 }
305 
309 
311 {
312  if (!length)
313  return E_INVALIDARG;
314 
315  *length = ME_GetTextLength(editor) + 1;
316  return S_OK;
317 }
318 
320 {
322 
324  switch (op)
325  {
326  case RANGE_UPDATE_DELETE:
327  /* range fully covered by deleted range - collapse to insertion point */
328  if (range->start >= start && range->end <= end)
329  range->start = range->end = start;
330  /* deleted range cuts from the right */
331  else if (range->start < start && range->end <= end)
332  range->end = start;
333  /* deleted range cuts from the left */
334  else if (range->start >= start && range->end > end) {
335  range->start = start;
336  range->end -= end - start;
337  }
338  /* deleted range cuts within */
339  else
340  range->end -= end - start;
341  break;
342  default:
343  FIXME("unknown update op, %d\n", op);
344  }
345  }
346 }
347 
350 {
351  switch (propid)
352  {
353  case FONT_ALLCAPS:
354  case FONT_ANIMATION:
355  case FONT_BACKCOLOR:
356  case FONT_BOLD:
357  case FONT_EMBOSS:
358  case FONT_FORECOLOR:
359  case FONT_HIDDEN:
360  case FONT_ENGRAVE:
361  case FONT_ITALIC:
362  case FONT_KERNING:
363  case FONT_LANGID:
364  case FONT_OUTLINE:
365  case FONT_PROTECTED:
366  case FONT_SHADOW:
367  case FONT_SMALLCAPS:
368  case FONT_STRIKETHROUGH:
369  case FONT_SUBSCRIPT:
370  case FONT_SUPERSCRIPT:
371  case FONT_UNDERLINE:
372  case FONT_WEIGHT:
373  return left->l == right->l;
374  case FONT_NAME:
375  return !strcmpW(left->str, right->str);
376  case FONT_POSITION:
377  case FONT_SIZE:
378  case FONT_SPACING:
379  return left->f == right->f;
380  default:
381  FIXME("unhandled font property %d\n", propid);
382  return FALSE;
383  }
384 }
385 
387 {
388  switch (propid)
389  {
390  case FONT_ALLCAPS:
391  case FONT_ANIMATION:
392  case FONT_BACKCOLOR:
393  case FONT_BOLD:
394  case FONT_EMBOSS:
395  case FONT_FORECOLOR:
396  case FONT_HIDDEN:
397  case FONT_ENGRAVE:
398  case FONT_ITALIC:
399  case FONT_KERNING:
400  case FONT_LANGID:
401  case FONT_OUTLINE:
402  case FONT_PROTECTED:
403  case FONT_SHADOW:
404  case FONT_SMALLCAPS:
405  case FONT_STRIKETHROUGH:
406  case FONT_SUBSCRIPT:
407  case FONT_SUPERSCRIPT:
408  case FONT_UNDERLINE:
409  case FONT_WEIGHT:
410  v->l = tomUndefined;
411  return;
412  case FONT_NAME:
413  v->str = NULL;
414  return;
415  case FONT_POSITION:
416  case FONT_SIZE:
417  case FONT_SPACING:
418  v->f = tomUndefined;
419  return;
420  default:
421  FIXME("unhandled font property %d\n", propid);
422  v->l = tomUndefined;
423  return;
424  }
425 }
426 
428 {
429  return value * 72.0 / 1440;
430 }
431 
433 {
434  return value * 1440 / 72.0;
435 }
436 
439 {
440  ME_Cursor from, to;
442 
443  memset(&fmt, 0, sizeof(fmt));
444  fmt.cbSize = sizeof(fmt);
445  fmt.dwMask = textfont_prop_masks[propid][0];
446 
448  to = from;
450  ME_GetCharFormat(reole->editor, &from, &to, &fmt);
451 
452  switch (propid)
453  {
454  case FONT_ALLCAPS:
455  case FONT_BOLD:
456  case FONT_EMBOSS:
457  case FONT_HIDDEN:
458  case FONT_ENGRAVE:
459  case FONT_ITALIC:
460  case FONT_OUTLINE:
461  case FONT_PROTECTED:
462  case FONT_SHADOW:
463  case FONT_SMALLCAPS:
464  case FONT_STRIKETHROUGH:
465  case FONT_SUBSCRIPT:
466  case FONT_SUPERSCRIPT:
467  case FONT_UNDERLINE:
468  value->l = fmt.dwEffects & textfont_prop_masks[propid][1] ? tomTrue : tomFalse;
469  break;
470  case FONT_ANIMATION:
471  value->l = fmt.bAnimation;
472  break;
473  case FONT_BACKCOLOR:
474  value->l = fmt.dwEffects & CFE_AUTOBACKCOLOR ? GetSysColor(COLOR_WINDOW) : fmt.crBackColor;
475  break;
476  case FONT_FORECOLOR:
477  value->l = fmt.dwEffects & CFE_AUTOCOLOR ? GetSysColor(COLOR_WINDOWTEXT) : fmt.crTextColor;
478  break;
479  case FONT_KERNING:
480  value->f = twips_to_points(fmt.wKerning);
481  break;
482  case FONT_LANGID:
483  value->l = fmt.lcid;
484  break;
485  case FONT_NAME:
486  /* this case is used exclusively by GetName() */
487  value->str = SysAllocString(fmt.szFaceName);
488  if (!value->str)
489  return E_OUTOFMEMORY;
490  break;
491  case FONT_POSITION:
492  value->f = twips_to_points(fmt.yOffset);
493  break;
494  case FONT_SIZE:
495  value->f = twips_to_points(fmt.yHeight);
496  break;
497  case FONT_SPACING:
498  value->f = fmt.sSpacing;
499  break;
500  case FONT_WEIGHT:
501  value->l = fmt.wWeight;
502  break;
503  default:
504  FIXME("unhandled font property %d\n", propid);
505  return E_FAIL;
506  }
507 
508  return S_OK;
509 }
510 
512 {
514  ITextRange_QueryInterface(range, &IID_Igetrichole, (void**)&reole);
515  return reole;
516 }
517 
519 {
521  HRESULT hr;
522  LONG value;
523  BSTR str;
524  FLOAT f;
525 
526 #define CHARFORMAT_SET_B_FIELD(mask, value) \
527  if (hr == S_OK && value != tomUndefined) { \
528  fmt.dwMask |= CFM_##mask; \
529  if (value == tomTrue) fmt.dwEffects |= CFE_##mask; \
530  } \
531 
532  /* fill format data from font */
533  memset(&fmt, 0, sizeof(fmt));
534  fmt.cbSize = sizeof(fmt);
535 
537  hr = ITextFont_GetAllCaps(font, &value);
538  CHARFORMAT_SET_B_FIELD(ALLCAPS, value);
539 
541  hr = ITextFont_GetBold(font, &value);
543 
545  hr = ITextFont_GetEmboss(font, &value);
546  CHARFORMAT_SET_B_FIELD(EMBOSS, value);
547 
549  hr = ITextFont_GetHidden(font, &value);
551 
553  hr = ITextFont_GetEngrave(font, &value);
554  CHARFORMAT_SET_B_FIELD(IMPRINT, value);
555 
557  hr = ITextFont_GetItalic(font, &value);
559 
561  hr = ITextFont_GetOutline(font, &value);
562  CHARFORMAT_SET_B_FIELD(OUTLINE, value);
563 
565  hr = ITextFont_GetProtected(font, &value);
566  CHARFORMAT_SET_B_FIELD(PROTECTED, value);
567 
569  hr = ITextFont_GetShadow(font, &value);
570  CHARFORMAT_SET_B_FIELD(SHADOW, value);
571 
573  hr = ITextFont_GetSmallCaps(font, &value);
574  CHARFORMAT_SET_B_FIELD(SMALLCAPS, value);
575 
577  hr = ITextFont_GetStrikeThrough(font, &value);
578  CHARFORMAT_SET_B_FIELD(STRIKEOUT, value);
579 
581  hr = ITextFont_GetSubscript(font, &value);
583 
585  hr = ITextFont_GetSuperscript(font, &value);
586  CHARFORMAT_SET_B_FIELD(SUPERSCRIPT, value);
587 
589  hr = ITextFont_GetUnderline(font, &value);
590  CHARFORMAT_SET_B_FIELD(UNDERLINE, value);
591 
592 #undef CHARFORMAT_SET_B_FIELD
593 
595  hr = ITextFont_GetAnimation(font, &value);
596  if (hr == S_OK && value != tomUndefined) {
597  fmt.dwMask |= CFM_ANIMATION;
598  fmt.bAnimation = value;
599  }
600 
602  hr = ITextFont_GetBackColor(font, &value);
603  if (hr == S_OK && value != tomUndefined) {
604  fmt.dwMask |= CFM_BACKCOLOR;
605  if (value == tomAutoColor)
606  fmt.dwEffects |= CFE_AUTOBACKCOLOR;
607  else
608  fmt.crBackColor = value;
609  }
610 
612  hr = ITextFont_GetForeColor(font, &value);
613  if (hr == S_OK && value != tomUndefined) {
614  fmt.dwMask |= CFM_COLOR;
615  if (value == tomAutoColor)
616  fmt.dwEffects |= CFE_AUTOCOLOR;
617  else
618  fmt.crTextColor = value;
619  }
620 
622  hr = ITextFont_GetKerning(font, &f);
623  if (hr == S_OK && f != tomUndefined) {
624  fmt.dwMask |= CFM_KERNING;
625  fmt.wKerning = points_to_twips(f);
626  }
627 
629  hr = ITextFont_GetLanguageID(font, &value);
630  if (hr == S_OK && value != tomUndefined) {
631  fmt.dwMask |= CFM_LCID;
632  fmt.lcid = value;
633  }
634 
635  if (ITextFont_GetName(font, &str) == S_OK) {
636  fmt.dwMask |= CFM_FACE;
637  lstrcpynW(fmt.szFaceName, str, ARRAY_SIZE(fmt.szFaceName));
639  }
640 
641  hr = ITextFont_GetPosition(font, &f);
642  if (hr == S_OK && f != tomUndefined) {
643  fmt.dwMask |= CFM_OFFSET;
644  fmt.yOffset = points_to_twips(f);
645  }
646 
647  hr = ITextFont_GetSize(font, &f);
648  if (hr == S_OK && f != tomUndefined) {
649  fmt.dwMask |= CFM_SIZE;
650  fmt.yHeight = points_to_twips(f);
651  }
652 
653  hr = ITextFont_GetSpacing(font, &f);
654  if (hr == S_OK && f != tomUndefined) {
655  fmt.dwMask |= CFM_SPACING;
656  fmt.sSpacing = f;
657  }
658 
659  hr = ITextFont_GetWeight(font, &value);
660  if (hr == S_OK && value != tomUndefined) {
661  fmt.dwMask |= CFM_WEIGHT;
662  fmt.wWeight = value;
663  }
664 
665  if (fmt.dwMask) {
667  ME_Cursor from, to;
668  LONG start, end;
669 
670  ITextRange_GetStart(range, &start);
671  ITextRange_GetEnd(range, &end);
672 
675  ME_SetCharFormat(reole->editor, &from, &to, &fmt);
676  }
677 }
678 
680 {
681  const IRichEditOleImpl *reole;
683  LONG start, end, i;
684  HRESULT hr;
685 
686  /* when font is not attached to any range use cached values */
687  if (!font->range || font->get_cache_enabled) {
688  *value = font->props[propid];
689  return S_OK;
690  }
691 
692  if (!(reole = get_range_reole(font->range)))
693  return CO_E_RELEASED;
694 
696 
697  ITextRange_GetStart(font->range, &start);
698  ITextRange_GetEnd(font->range, &end);
699 
700  /* iterate trough a range to see if property value is consistent */
701  hr = get_textfont_prop_for_pos(reole, start, propid, &v);
702  if (FAILED(hr))
703  return hr;
704 
705  for (i = start + 1; i < end; i++) {
706  textfont_prop_val cur;
707 
708  hr = get_textfont_prop_for_pos(reole, i, propid, &cur);
709  if (FAILED(hr))
710  return hr;
711 
712  if (!is_equal_textfont_prop_value(propid, &v, &cur))
713  return S_OK;
714  }
715 
716  *value = v;
717  return S_OK;
718 }
719 
721 {
723  HRESULT hr;
724 
725  if (!value)
726  return E_INVALIDARG;
727 
728  hr = get_textfont_prop(font, propid, &v);
729  *value = v.f;
730  return hr;
731 }
732 
734 {
736  HRESULT hr;
737 
738  if (!value)
739  return E_INVALIDARG;
740 
741  hr = get_textfont_prop(font, propid, &v);
742  *value = v.l;
743  return hr;
744 }
745 
746 /* Value should already have a terminal value, for boolean properties it means tomToggle is not handled */
748 {
749  const IRichEditOleImpl *reole;
750  ME_Cursor from, to;
752  LONG start, end;
753 
754  /* when font is not attached to any range use cache */
755  if (!font->range || font->set_cache_enabled) {
756  if (propid == FONT_NAME) {
757  SysFreeString(font->props[propid].str);
758  font->props[propid].str = SysAllocString(value->str);
759  }
760  else
761  font->props[propid] = *value;
762  return S_OK;
763  }
764 
765  if (!(reole = get_range_reole(font->range)))
766  return CO_E_RELEASED;
767 
768  memset(&fmt, 0, sizeof(fmt));
769  fmt.cbSize = sizeof(fmt);
770  fmt.dwMask = textfont_prop_masks[propid][0];
771 
772  switch (propid)
773  {
774  case FONT_ALLCAPS:
775  case FONT_BOLD:
776  case FONT_EMBOSS:
777  case FONT_HIDDEN:
778  case FONT_ENGRAVE:
779  case FONT_ITALIC:
780  case FONT_OUTLINE:
781  case FONT_PROTECTED:
782  case FONT_SHADOW:
783  case FONT_SMALLCAPS:
784  case FONT_STRIKETHROUGH:
785  case FONT_SUBSCRIPT:
786  case FONT_SUPERSCRIPT:
787  case FONT_UNDERLINE:
788  fmt.dwEffects = value->l == tomTrue ? textfont_prop_masks[propid][1] : 0;
789  break;
790  case FONT_ANIMATION:
791  fmt.bAnimation = value->l;
792  break;
793  case FONT_BACKCOLOR:
794  case FONT_FORECOLOR:
795  if (value->l == tomAutoColor)
796  fmt.dwEffects = textfont_prop_masks[propid][1];
797  else if (propid == FONT_BACKCOLOR)
798  fmt.crBackColor = value->l;
799  else
800  fmt.crTextColor = value->l;
801  break;
802  case FONT_KERNING:
803  fmt.wKerning = value->f;
804  break;
805  case FONT_LANGID:
806  fmt.lcid = value->l;
807  break;
808  case FONT_POSITION:
809  fmt.yOffset = value->f;
810  break;
811  case FONT_SIZE:
812  fmt.yHeight = value->f;
813  break;
814  case FONT_SPACING:
815  fmt.sSpacing = value->f;
816  break;
817  case FONT_WEIGHT:
818  fmt.wWeight = value->l;
819  break;
820  case FONT_NAME:
821  lstrcpynW(fmt.szFaceName, value->str, ARRAY_SIZE(fmt.szFaceName));
822  break;
823  default:
824  FIXME("unhandled font property %d\n", propid);
825  return E_FAIL;
826  }
827 
828  ITextRange_GetStart(font->range, &start);
829  ITextRange_GetEnd(font->range, &end);
830 
833  ME_SetCharFormat(reole->editor, &from, &to, &fmt);
834 
835  return S_OK;
836 }
837 
839 {
841  v.l = value;
842  return set_textfont_prop(font, propid, &v);
843 }
844 
846 {
848  v.f = value;
849  return set_textfont_prop(font, propid, &v);
850 }
851 
853 {
855 
856  switch (value)
857  {
858  case tomUndefined:
859  return S_OK;
860  case tomToggle: {
861  LONG oldvalue;
862  get_textfont_propl(font, propid, &oldvalue);
863  if (oldvalue == tomFalse)
864  value = tomTrue;
865  else if (oldvalue == tomTrue)
866  value = tomFalse;
867  else
868  return E_INVALIDARG;
869  /* fallthrough */
870  }
871  case tomTrue:
872  case tomFalse:
873  v.l = value;
874  return set_textfont_prop(font, propid, &v);
875  default:
876  return E_INVALIDARG;
877  }
878 }
879 
881 {
882  const IRichEditOleImpl *reole;
884  HRESULT hr;
885  LONG start;
886 
887  if (!(reole = get_range_reole(range)))
888  return CO_E_RELEASED;
889 
890  ITextRange_GetStart(range, &start);
892  *ret = v.str;
893  return hr;
894 }
895 
897 {
898  enum textfont_prop_id propid;
899  for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++) {
900  if (propid == FONT_NAME)
901  textfont_getname_from_range(font->range, &font->props[propid].str);
902  else
903  get_textfont_prop(font, propid, &font->props[propid]);
904  }
905 }
906 
908 {
909  LONG expand_start, expand_end;
910 
911  switch (unit)
912  {
913  case tomStory:
914  expand_start = 0;
915  ITextRange_GetStoryLength(range, &expand_end);
916  break;
917  default:
918  FIXME("unit %d is not supported\n", unit);
919  return E_NOTIMPL;
920  }
921 
922  if (delta) {
923  LONG start, end;
924 
925  ITextRange_GetStart(range, &start);
926  ITextRange_GetEnd(range, &end);
927  *delta = expand_end - expand_start - (end - start);
928  }
929 
930  ITextRange_SetStart(range, expand_start);
931  ITextRange_SetEnd(range, expand_end);
932 
933  return S_OK;
934 }
935 
937 {
939 
940  TRACE("%p %s\n", This, debugstr_guid(riid));
941 
942  *ppvObj = NULL;
944  *ppvObj = &This->IUnknown_inner;
945  else if (IsEqualGUID(riid, &IID_IRichEditOle))
946  *ppvObj = &This->IRichEditOle_iface;
947  else if (IsEqualGUID(riid, &IID_ITextDocument) || IsEqualGUID(riid, &IID_ITextDocument2Old))
948  *ppvObj = &This->ITextDocument2Old_iface;
949  if (*ppvObj)
950  {
951  IUnknown_AddRef((IUnknown *)*ppvObj);
952  return S_OK;
953  }
954 
955  if (IsEqualGUID(riid, &IID_ITextServices))
956  {
957  static int once;
958  if (!once++) FIXME("%p: unhandled interface IID_ITextServices\n", This);
959  return E_NOINTERFACE;
960  }
961 
962  FIXME("%p: unhandled interface %s\n", This, debugstr_guid(riid));
963 
964  return E_NOINTERFACE;
965 }
966 
968 {
971 
972  TRACE("%p ref = %u\n", This, ref);
973 
974  return ref;
975 }
976 
978 {
981 
982  TRACE ("%p ref=%u\n", This, ref);
983 
984  if (!ref)
985  {
986  IOleClientSiteImpl *clientsite;
987  ITextRangeImpl *txtRge;
988 
989  This->editor->reOle = NULL;
990  if (This->txtSel) {
991  This->txtSel->reOle = NULL;
992  ITextSelection_Release(&This->txtSel->ITextSelection_iface);
993  }
994 
995  LIST_FOR_EACH_ENTRY(txtRge, &This->rangelist, ITextRangeImpl, child.entry)
996  txtRge->child.reole = NULL;
997 
998  LIST_FOR_EACH_ENTRY(clientsite, &This->clientsites, IOleClientSiteImpl, child.entry)
999  clientsite->child.reole = NULL;
1000 
1001  heap_free(This);
1002  }
1003  return ref;
1004 }
1005 
1006 static const IUnknownVtbl reo_unk_vtbl =
1007 {
1011 };
1012 
1013 static HRESULT WINAPI
1015 {
1017  return IUnknown_QueryInterface(This->outer_unk, riid, ppvObj);
1018 }
1019 
1020 static ULONG WINAPI
1022 {
1024  return IUnknown_AddRef(This->outer_unk);
1025 }
1026 
1027 static ULONG WINAPI
1029 {
1031  return IUnknown_Release(This->outer_unk);
1032 }
1033 
1034 static HRESULT WINAPI
1036 {
1038  FIXME("stub %p\n",This);
1039  return E_NOTIMPL;
1040 }
1041 
1042 static HRESULT WINAPI
1044 {
1046  FIXME("stub %p\n",This);
1047  return E_NOTIMPL;
1048 }
1049 
1050 static HRESULT WINAPI
1052  REFCLSID rclsidNew, LPCSTR lpstrUserTypeNew)
1053 {
1055  FIXME("stub %p\n",This);
1056  return E_NOTIMPL;
1057 }
1058 
1060 {
1061  return CONTAINING_RECORD(iface, IOleClientSiteImpl, IOleClientSite_iface);
1062 }
1063 
1064 static HRESULT WINAPI
1066 {
1068  TRACE("%p %s\n", me, debugstr_guid(riid) );
1069 
1070  *ppvObj = NULL;
1071  if (IsEqualGUID(riid, &IID_IUnknown) ||
1073  *ppvObj = me;
1074  else if (IsEqualGUID(riid, &IID_IOleWindow) ||
1076  *ppvObj = &This->IOleInPlaceSite_iface;
1077  if (*ppvObj)
1078  {
1079  IOleClientSite_AddRef(me);
1080  return S_OK;
1081  }
1082  FIXME("%p: unhandled interface %s\n", me, debugstr_guid(riid) );
1083 
1084  return E_NOINTERFACE;
1085 }
1086 
1088 {
1091  TRACE("(%p)->(%u)\n", This, ref);
1092  return ref;
1093 }
1094 
1096 {
1099 
1100  TRACE("(%p)->(%u)\n", This, ref);
1101 
1102  if (ref == 0) {
1103  if (This->child.reole) {
1104  list_remove(&This->child.entry);
1105  This->child.reole = NULL;
1106  }
1107  heap_free(This);
1108  }
1109  return ref;
1110 }
1111 
1113 {
1115  if (!This->child.reole)
1116  return CO_E_RELEASED;
1117 
1118  FIXME("stub %p\n", iface);
1119  return E_NOTIMPL;
1120 }
1121 
1123  DWORD dwWhichMoniker, IMoniker **ppmk)
1124 {
1126  if (!This->child.reole)
1127  return CO_E_RELEASED;
1128 
1129  FIXME("stub %p\n", iface);
1130  return E_NOTIMPL;
1131 }
1132 
1134  IOleContainer **ppContainer)
1135 {
1137  if (!This->child.reole)
1138  return CO_E_RELEASED;
1139 
1140  FIXME("stub %p\n", iface);
1141  return E_NOTIMPL;
1142 }
1143 
1145 {
1147  if (!This->child.reole)
1148  return CO_E_RELEASED;
1149 
1150  FIXME("stub %p\n", iface);
1151  return E_NOTIMPL;
1152 }
1153 
1155 {
1157  if (!This->child.reole)
1158  return CO_E_RELEASED;
1159 
1160  FIXME("stub %p\n", iface);
1161  return E_NOTIMPL;
1162 }
1163 
1165 {
1167  if (!This->child.reole)
1168  return CO_E_RELEASED;
1169 
1170  FIXME("stub %p\n", iface);
1171  return E_NOTIMPL;
1172 }
1173 
1174 static const IOleClientSiteVtbl ocst = {
1184 };
1185 
1186 /* IOleInPlaceSite interface */
1188 {
1190  return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppvObj);
1191 }
1192 
1194 {
1196  return IOleClientSite_AddRef(&This->IOleClientSite_iface);
1197 }
1198 
1200 {
1202  return IOleClientSite_Release(&This->IOleClientSite_iface);
1203 }
1204 
1206 {
1208 
1209  TRACE("(%p)->(%p)\n", This, phwnd);
1210 
1211  if (!This->child.reole)
1212  return CO_E_RELEASED;
1213 
1214  if (!phwnd)
1215  return E_INVALIDARG;
1216 
1217  *phwnd = This->child.reole->editor->hWnd;
1218  return S_OK;
1219 }
1220 
1222 {
1224  FIXME("not implemented: (%p)->(%d)\n", This, fEnterMode);
1225  return E_NOTIMPL;
1226 }
1227 
1229 {
1231  FIXME("not implemented: (%p)\n", This);
1232  return E_NOTIMPL;
1233 }
1234 
1236 {
1238  FIXME("not implemented: (%p)\n", This);
1239  return E_NOTIMPL;
1240 }
1241 
1243 {
1245  FIXME("not implemented: (%p)\n", This);
1246  return E_NOTIMPL;
1247 }
1248 
1250  IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect,
1251  LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
1252 {
1254  FIXME("not implemented: (%p)->(%p %p %p %p %p)\n", This, ppFrame, ppDoc, lprcPosRect, lprcClipRect, lpFrameInfo);
1255  return E_NOTIMPL;
1256 }
1257 
1259 {
1261  FIXME("not implemented: (%p)\n", This);
1262  return E_NOTIMPL;
1263 }
1264 
1266 {
1268  FIXME("not implemented: (%p)->(%d)\n", This, fUndoable);
1269  return E_NOTIMPL;
1270 }
1271 
1273 {
1275  FIXME("not implemented: (%p)\n", This);
1276  return E_NOTIMPL;
1277 }
1278 
1280 {
1282  FIXME("not implemented: (%p)\n", This);
1283  return E_NOTIMPL;
1284 }
1285 
1287 {
1289  FIXME("not implemented: (%p)\n", This);
1290  return E_NOTIMPL;
1291 }
1292 
1294 {
1296  FIXME("not implemented: (%p)->(%p)\n", This, lprcPosRect);
1297  return E_NOTIMPL;
1298 }
1299 
1300 static const IOleInPlaceSiteVtbl olestvt =
1301 {
1317 };
1318 
1320 {
1321  IOleClientSiteImpl *clientSite = heap_alloc(sizeof *clientSite);
1322 
1323  if (!clientSite)
1324  return E_OUTOFMEMORY;
1325 
1326  clientSite->IOleClientSite_iface.lpVtbl = &ocst;
1327  clientSite->IOleInPlaceSite_iface.lpVtbl = &olestvt;
1328  clientSite->ref = 1;
1329  clientSite->child.reole = reOle;
1330  list_add_head(&reOle->clientsites, &clientSite->child.entry);
1331 
1332  *ret = &clientSite->IOleClientSite_iface;
1333  return S_OK;
1334 }
1335 
1336 static HRESULT WINAPI
1338 {
1340 
1341  TRACE("(%p)->(%p)\n", This, clientsite);
1342 
1343  if (!clientsite)
1344  return E_INVALIDARG;
1345 
1346  return CreateOleClientSite(This, clientsite);
1347 }
1348 
1349 static HRESULT WINAPI
1351  DWORD reco, LPDATAOBJECT *lplpdataobj)
1352 {
1354  ME_Cursor start;
1355  int nChars;
1356 
1357  TRACE("(%p,%p,%d)\n",This, lpchrg, reco);
1358  if(!lplpdataobj)
1359  return E_INVALIDARG;
1360  if(!lpchrg) {
1361  int nFrom, nTo, nStartCur = ME_GetSelectionOfs(This->editor, &nFrom, &nTo);
1362  start = This->editor->pCursors[nStartCur];
1363  nChars = nTo - nFrom;
1364  } else {
1365  ME_CursorFromCharOfs(This->editor, lpchrg->cpMin, &start);
1366  nChars = lpchrg->cpMax - lpchrg->cpMin;
1367  }
1368  return ME_GetDataObject(This->editor, &start, nChars, lplpdataobj);
1369 }
1370 
1372 {
1374  FIXME("stub %p\n",This);
1375  return E_NOTIMPL;
1376 }
1377 
1378 static HRESULT WINAPI
1380  REOBJECT *lpreobject, DWORD dwFlags)
1381 {
1383  struct re_object *reobj = NULL;
1384  LONG count = 0;
1385 
1386  TRACE("(%p)->(%x, %p, %x)\n", This, iob, lpreobject, dwFlags);
1387 
1388  if (!lpreobject || !lpreobject->cbStruct)
1389  return E_INVALIDARG;
1390 
1391  if (iob == REO_IOB_USE_CP)
1392  {
1393  ME_Cursor cursor;
1394 
1395  TRACE("character offset: %d\n", lpreobject->cp);
1396  ME_CursorFromCharOfs(This->editor, lpreobject->cp, &cursor);
1397  if (!cursor.pRun->member.run.reobj)
1398  return E_INVALIDARG;
1399  else
1400  reobj = cursor.pRun->member.run.reobj;
1401  }
1402  else
1403  {
1404  if (iob > IRichEditOle_GetObjectCount(me))
1405  return E_INVALIDARG;
1406  LIST_FOR_EACH_ENTRY(reobj, &This->editor->reobj_list, struct re_object, entry)
1407  {
1408  if (count == iob)
1409  break;
1410  count++;
1411  }
1412  }
1413  ME_CopyReObject(lpreobject, &reobj->obj, dwFlags);
1414  return S_OK;
1415 }
1416 
1417 static LONG WINAPI
1419 {
1421  TRACE("(%p)\n",This);
1422  return list_count(&This->editor->reobj_list);
1423 }
1424 
1425 static HRESULT WINAPI
1427 {
1429  FIXME("stub %p\n",This);
1430  return E_NOTIMPL;
1431 }
1432 
1433 static HRESULT WINAPI
1435  CLIPFORMAT cf, HGLOBAL hMetaPict)
1436 {
1438  FIXME("stub %p\n",This);
1439  return E_NOTIMPL;
1440 }
1441 
1442 static HRESULT WINAPI
1444 {
1446  FIXME("stub %p\n",This);
1447  return E_NOTIMPL;
1448 }
1449 
1450 static HRESULT WINAPI
1452 {
1454 
1455  TRACE("(%p,%p)\n", This, reo);
1456 
1457  if (!reo)
1458  return E_INVALIDARG;
1459 
1460  if (reo->cbStruct < sizeof(*reo)) return STG_E_INVALIDPARAMETER;
1461 
1462  ME_InsertOLEFromCursor(This->editor, reo, 0);
1463  ME_CommitUndo(This->editor);
1464  ME_UpdateRepaint(This->editor, FALSE);
1465  return S_OK;
1466 }
1467 
1469  LPSTORAGE lpstg)
1470 {
1472  FIXME("stub %p\n",This);
1473  return E_NOTIMPL;
1474 }
1475 
1476 static HRESULT WINAPI
1478 {
1480  FIXME("stub %p\n",This);
1481  return E_NOTIMPL;
1482 }
1483 
1485  LPCSTR lpstrContainerApp, LPCSTR lpstrContainerObj)
1486 {
1488  FIXME("stub %p %s %s\n",This, lpstrContainerApp, lpstrContainerObj);
1489  return E_NOTIMPL;
1490 }
1491 
1492 static HRESULT WINAPI
1494 {
1496  FIXME("stub %p\n",This);
1497  return E_NOTIMPL;
1498 }
1499 
1500 static const IRichEditOleVtbl revt = {
1520 };
1521 
1522 /* ITextRange interface */
1524 {
1526 
1527  *ppvObj = NULL;
1530  || IsEqualGUID(riid, &IID_ITextRange))
1531  {
1532  *ppvObj = me;
1533  ITextRange_AddRef(me);
1534  return S_OK;
1535  }
1536  else if (IsEqualGUID(riid, &IID_Igetrichole))
1537  {
1538  *ppvObj = This->child.reole;
1539  return S_OK;
1540  }
1541 
1542  return E_NOINTERFACE;
1543 }
1544 
1546 {
1548  return InterlockedIncrement(&This->ref);
1549 }
1550 
1552 {
1555 
1556  TRACE ("%p ref=%u\n", This, ref);
1557  if (ref == 0)
1558  {
1559  if (This->child.reole)
1560  {
1561  list_remove(&This->child.entry);
1562  This->child.reole = NULL;
1563  }
1564  heap_free(This);
1565  }
1566  return ref;
1567 }
1568 
1570 {
1572  TRACE("(%p)->(%p)\n", This, pctinfo);
1573  *pctinfo = 1;
1574  return S_OK;
1575 }
1576 
1578  ITypeInfo **ppTInfo)
1579 {
1581  HRESULT hr;
1582 
1583  TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
1584 
1585  hr = get_typeinfo(ITextRange_tid, ppTInfo);
1586  if (SUCCEEDED(hr))
1587  ITypeInfo_AddRef(*ppTInfo);
1588  return hr;
1589 }
1590 
1592  UINT cNames, LCID lcid, DISPID *rgDispId)
1593 {
1595  ITypeInfo *ti;
1596  HRESULT hr;
1597 
1598  TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid,
1599  rgDispId);
1600 
1601  hr = get_typeinfo(ITextRange_tid, &ti);
1602  if (SUCCEEDED(hr))
1603  hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
1604  return hr;
1605 }
1606 
1608  LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1609  VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
1610  UINT *puArgErr)
1611 {
1613  ITypeInfo *ti;
1614  HRESULT hr;
1615 
1616  TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid),
1617  lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1618 
1619  hr = get_typeinfo(ITextRange_tid, &ti);
1620  if (SUCCEEDED(hr))
1621  hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1622  return hr;
1623 }
1624 
1626 {
1628  ME_TextEditor *editor;
1629  ME_Cursor start, end;
1630  int length;
1631  BOOL bEOP;
1632 
1633  TRACE("(%p)->(%p)\n", This, str);
1634 
1635  if (!This->child.reole)
1636  return CO_E_RELEASED;
1637 
1638  if (!str)
1639  return E_INVALIDARG;
1640 
1641  /* return early for degenerate range */
1642  if (This->start == This->end) {
1643  *str = NULL;
1644  return S_OK;
1645  }
1646 
1647  editor = This->child.reole->editor;
1648  ME_CursorFromCharOfs(editor, This->start, &start);
1649  ME_CursorFromCharOfs(editor, This->end, &end);
1650 
1651  length = This->end - This->start;
1653  if (!*str)
1654  return E_OUTOFMEMORY;
1655 
1656  bEOP = (end.pRun->next->type == diTextEnd && This->end > ME_GetTextLength(editor));
1657  ME_GetTextW(editor, *str, length, &start, length, FALSE, bEOP);
1658  return S_OK;
1659 }
1660 
1662 {
1664  ME_TextEditor *editor;
1665  ME_Cursor cursor;
1666  ME_Style *style;
1667  int len;
1668 
1669  TRACE("(%p)->(%s)\n", This, debugstr_w(str));
1670 
1671  if (!This->child.reole)
1672  return CO_E_RELEASED;
1673 
1674  editor = This->child.reole->editor;
1675 
1676  /* delete only where's something to delete */
1677  if (This->start != This->end) {
1678  ME_CursorFromCharOfs(editor, This->start, &cursor);
1679  ME_InternalDeleteText(editor, &cursor, This->end - This->start, FALSE);
1680  }
1681 
1682  if (!str || !*str) {
1683  /* will update this range as well */
1684  textranges_update_ranges(This->child.reole, This->start, This->end, RANGE_UPDATE_DELETE);
1685  return S_OK;
1686  }
1687 
1688  /* it's safer not to rely on stored BSTR length */
1689  len = strlenW(str);
1690  cursor = editor->pCursors[0];
1691  ME_CursorFromCharOfs(editor, This->start, &editor->pCursors[0]);
1692  style = ME_GetInsertStyle(editor, 0);
1693  ME_InsertTextFromCursor(editor, 0, str, len, style);
1695  editor->pCursors[0] = cursor;
1696 
1697  if (len < This->end - This->start)
1698  textranges_update_ranges(This->child.reole, This->start + len, This->end, RANGE_UPDATE_DELETE);
1699  else
1700  This->end = len - This->start;
1701 
1702  return S_OK;
1703 }
1704 
1706 {
1707  WCHAR wch[2];
1708 
1709  ME_GetTextW(editor, wch, 1, cursor, 1, FALSE, cursor->pRun->next->type == diTextEnd);
1710  *pch = wch[0];
1711 
1712  return S_OK;
1713 }
1714 
1716 {
1718  ME_TextEditor *editor;
1719  ME_Cursor cursor;
1720 
1721  TRACE("(%p)->(%p)\n", This, pch);
1722 
1723  if (!This->child.reole)
1724  return CO_E_RELEASED;
1725 
1726  if (!pch)
1727  return E_INVALIDARG;
1728 
1729  editor = This->child.reole->editor;
1730  ME_CursorFromCharOfs(editor, This->start, &cursor);
1731  return range_GetChar(editor, &cursor, pch);
1732 }
1733 
1735 {
1737 
1738  FIXME("(%p)->(%x): stub\n", This, ch);
1739 
1740  if (!This->child.reole)
1741  return CO_E_RELEASED;
1742 
1743  return E_NOTIMPL;
1744 }
1745 
1747 
1749 {
1751 
1752  TRACE("(%p)->(%p)\n", This, ppRange);
1753 
1754  if (!This->child.reole)
1755  return CO_E_RELEASED;
1756 
1757  if (!ppRange)
1758  return E_INVALIDARG;
1759 
1760  return CreateITextRange(This->child.reole, This->start, This->end, ppRange);
1761 }
1762 
1764 {
1766 
1767  FIXME("(%p)->(%p): stub\n", This, range);
1768 
1769  if (!This->child.reole)
1770  return CO_E_RELEASED;
1771 
1772  return E_NOTIMPL;
1773 }
1774 
1776 {
1778 
1779  FIXME("(%p)->(%p): stub\n", This, range);
1780 
1781  if (!This->child.reole)
1782  return CO_E_RELEASED;
1783 
1784  return E_NOTIMPL;
1785 }
1786 
1788 {
1790 
1791  TRACE("(%p)->(%p)\n", This, start);
1792 
1793  if (!This->child.reole)
1794  return CO_E_RELEASED;
1795 
1796  if (!start)
1797  return E_INVALIDARG;
1798 
1799  *start = This->start;
1800  return S_OK;
1801 }
1802 
1804 {
1805  int len;
1806 
1807  if (value < 0)
1808  value = 0;
1809 
1810  if (value == *start)
1811  return S_FALSE;
1812 
1813  if (value <= *end) {
1814  *start = value;
1815  return S_OK;
1816  }
1817 
1818  len = ME_GetTextLength(reole->editor);
1819  *start = *end = value > len ? len : value;
1820  return S_OK;
1821 }
1822 
1824 {
1826 
1827  TRACE("(%p)->(%d)\n", This, value);
1828 
1829  if (!This->child.reole)
1830  return CO_E_RELEASED;
1831 
1832  return textrange_setstart(This->child.reole, value, &This->start, &This->end);
1833 }
1834 
1836 {
1838 
1839  TRACE("(%p)->(%p)\n", This, end);
1840 
1841  if (!This->child.reole)
1842  return CO_E_RELEASED;
1843 
1844  if (!end)
1845  return E_INVALIDARG;
1846 
1847  *end = This->end;
1848  return S_OK;
1849 }
1850 
1852 {
1853  int len;
1854 
1855  if (value == *end)
1856  return S_FALSE;
1857 
1858  if (value < *start) {
1859  *start = *end = max(0, value);
1860  return S_OK;
1861  }
1862 
1863  len = ME_GetTextLength(reole->editor);
1864  *end = value > len ? len + 1 : value;
1865  return S_OK;
1866 }
1867 
1869 {
1871 
1872  TRACE("(%p)->(%d)\n", This, value);
1873 
1874  if (!This->child.reole)
1875  return CO_E_RELEASED;
1876 
1877  return textrange_setend(This->child.reole, value, &This->start, &This->end);
1878 }
1879 
1881 {
1883 
1884  TRACE("(%p)->(%p)\n", This, font);
1885 
1886  if (!This->child.reole)
1887  return CO_E_RELEASED;
1888 
1889  if (!font)
1890  return E_INVALIDARG;
1891 
1892  return create_textfont(me, NULL, font);
1893 }
1894 
1896 {
1898 
1899  TRACE("(%p)->(%p)\n", This, font);
1900 
1901  if (!font)
1902  return E_INVALIDARG;
1903 
1904  if (!This->child.reole)
1905  return CO_E_RELEASED;
1906 
1907  textrange_set_font(me, font);
1908  return S_OK;
1909 }
1910 
1912 {
1914 
1915  TRACE("(%p)->(%p)\n", This, para);
1916 
1917  if (!This->child.reole)
1918  return CO_E_RELEASED;
1919 
1920  if (!para)
1921  return E_INVALIDARG;
1922 
1923  return create_textpara(me, para);
1924 }
1925 
1927 {
1929 
1930  FIXME("(%p)->(%p): stub\n", This, para);
1931 
1932  if (!This->child.reole)
1933  return CO_E_RELEASED;
1934 
1935  return E_NOTIMPL;
1936 }
1937 
1939 {
1941 
1942  TRACE("(%p)->(%p)\n", This, length);
1943 
1944  if (!This->child.reole)
1945  return CO_E_RELEASED;
1946 
1947  return textrange_get_storylength(This->child.reole->editor, length);
1948 }
1949 
1951 {
1953 
1954  TRACE("(%p)->(%p)\n", This, value);
1955 
1956  if (!This->child.reole)
1957  return CO_E_RELEASED;
1958 
1959  if (!value)
1960  return E_INVALIDARG;
1961 
1963  return S_OK;
1964 }
1965 
1967 {
1968  if (*end == *start)
1969  return S_FALSE;
1970 
1971  if (bStart == tomEnd)
1972  *start = *end;
1973  else
1974  *end = *start;
1975  return S_OK;
1976 }
1977 
1979 {
1981 
1982  TRACE("(%p)->(%d)\n", This, bStart);
1983 
1984  if (!This->child.reole)
1985  return CO_E_RELEASED;
1986 
1987  return range_Collapse(bStart, &This->start, &This->end);
1988 }
1989 
1991 {
1993 
1994  TRACE("(%p)->(%d %p)\n", This, unit, delta);
1995 
1996  if (!This->child.reole)
1997  return CO_E_RELEASED;
1998 
1999  return textrange_expand(me, unit, delta);
2000 }
2001 
2003 {
2005 
2006  FIXME("(%p)->(%d %p): stub\n", This, unit, index);
2007 
2008  if (!This->child.reole)
2009  return CO_E_RELEASED;
2010 
2011  return E_NOTIMPL;
2012 }
2013 
2015  LONG extend)
2016 {
2018 
2019  FIXME("(%p)->(%d %d %d): stub\n", This, unit, index, extend);
2020 
2021  if (!This->child.reole)
2022  return CO_E_RELEASED;
2023 
2024  return E_NOTIMPL;
2025 }
2026 
2027 static void cp2range(ME_TextEditor *editor, LONG *cp1, LONG *cp2)
2028 {
2029  int len = ME_GetTextLength(editor) + 1;
2030  *cp1 = max(*cp1, 0);
2031  *cp2 = max(*cp2, 0);
2032  *cp1 = min(*cp1, len);
2033  *cp2 = min(*cp2, len);
2034  if (*cp1 > *cp2)
2035  {
2036  int tmp = *cp1;
2037  *cp1 = *cp2;
2038  *cp2 = tmp;
2039  }
2040  if (*cp1 == len)
2041  *cp1 = *cp2 = len - 1;
2042 }
2043 
2045 {
2047 
2048  FIXME("(%p)->(%d %d): stub\n", This, anchor, active);
2049 
2050  if (!This->child.reole)
2051  return CO_E_RELEASED;
2052 
2053  cp2range(This->child.reole->editor, &anchor, &active);
2054  if (anchor == This->start && active == This->end)
2055  return S_FALSE;
2056 
2057  This->start = anchor;
2058  This->end = active;
2059  return S_OK;
2060 }
2061 
2063 {
2064  LONG from, to, v;
2065 
2066  if (!ret)
2067  ret = &v;
2068 
2069  if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) {
2070  *ret = tomFalse;
2071  }
2072  else
2073  *ret = (start >= from && end <= to) ? tomTrue : tomFalse;
2074  return *ret == tomTrue ? S_OK : S_FALSE;
2075 }
2076 
2078 {
2080 
2081  TRACE("(%p)->(%p %p)\n", This, range, ret);
2082 
2083  if (ret)
2084  *ret = tomFalse;
2085 
2086  if (!This->child.reole)
2087  return CO_E_RELEASED;
2088 
2089  if (!range)
2090  return S_FALSE;
2091 
2092  return textrange_inrange(This->start, This->end, range, ret);
2093 }
2094 
2096 {
2098 
2099  FIXME("(%p)->(%p): stub\n", This, ret);
2100 
2101  if (!This->child.reole)
2102  return CO_E_RELEASED;
2103 
2104  return E_NOTIMPL;
2105 }
2106 
2108 {
2109  LONG from, to, v;
2110 
2111  if (!ret)
2112  ret = &v;
2113 
2114  if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) {
2115  *ret = tomFalse;
2116  }
2117  else
2118  *ret = (start == from && end == to) ? tomTrue : tomFalse;
2119  return *ret == tomTrue ? S_OK : S_FALSE;
2120 }
2121 
2123 {
2125 
2126  TRACE("(%p)->(%p %p)\n", This, range, ret);
2127 
2128  if (ret)
2129  *ret = tomFalse;
2130 
2131  if (!This->child.reole)
2132  return CO_E_RELEASED;
2133 
2134  if (!range)
2135  return S_FALSE;
2136 
2137  return textrange_isequal(This->start, This->end, range, ret);
2138 }
2139 
2141 {
2143 
2144  TRACE("(%p)\n", This);
2145 
2146  if (!This->child.reole)
2147  return CO_E_RELEASED;
2148 
2149  ME_SetSelection(This->child.reole->editor, This->start, This->end);
2150  return S_OK;
2151 }
2152 
2154  LONG *delta)
2155 {
2157 
2158  FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
2159 
2160  if (!This->child.reole)
2161  return CO_E_RELEASED;
2162 
2163  return E_NOTIMPL;
2164 }
2165 
2167  LONG *delta)
2168 {
2170 
2171  FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta);
2172 
2173  if (!This->child.reole)
2174  return CO_E_RELEASED;
2175 
2176  return E_NOTIMPL;
2177 }
2178 
2180 {
2182 
2183  FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
2184 
2185  if (!This->child.reole)
2186  return CO_E_RELEASED;
2187 
2188  return E_NOTIMPL;
2189 }
2190 
2192  LONG *delta)
2193 {
2195 
2196  FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
2197 
2198  if (!This->child.reole)
2199  return CO_E_RELEASED;
2200 
2201  return E_NOTIMPL;
2202 }
2203 
2205 {
2206  LONG old_start, old_end, new_start, new_end;
2207  HRESULT hr = S_OK;
2208 
2209  if (!count)
2210  {
2211  if (delta)
2212  *delta = 0;
2213  return S_FALSE;
2214  }
2215 
2216  ITextRange_GetStart(range, &old_start);
2217  ITextRange_GetEnd(range, &old_end);
2218  switch (unit)
2219  {
2220  case tomStory:
2221  if (count < 0)
2222  new_start = new_end = 0;
2223  else
2224  {
2225  new_start = old_start;
2226  ITextRange_GetStoryLength(range, &new_end);
2227  }
2228  if (delta)
2229  {
2230  if (new_end < old_end)
2231  *delta = -1;
2232  else if (new_end == old_end)
2233  *delta = 0;
2234  else
2235  *delta = 1;
2236  }
2237  break;
2238  default:
2239  FIXME("unit %d is not supported\n", unit);
2240  return E_NOTIMPL;
2241  }
2242  if (new_end == old_end)
2243  hr = S_FALSE;
2244  ITextRange_SetStart(range, new_start);
2245  ITextRange_SetEnd(range, new_end);
2246 
2247  return hr;
2248 }
2249 
2251  LONG *delta)
2252 {
2254 
2255  TRACE("(%p)->(%d %d %p)\n", This, unit, count, delta);
2256 
2257  if (!This->child.reole)
2258  return CO_E_RELEASED;
2259 
2260  return textrange_moveend(me, unit, count, delta);
2261 }
2262 
2264  LONG *delta)
2265 {
2267 
2268  FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2269 
2270  if (!This->child.reole)
2271  return CO_E_RELEASED;
2272 
2273  return E_NOTIMPL;
2274 }
2275 
2277  LONG *delta)
2278 {
2280 
2281  FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2282 
2283  if (!This->child.reole)
2284  return CO_E_RELEASED;
2285 
2286  return E_NOTIMPL;
2287 }
2288 
2290  LONG *delta)
2291 {
2293 
2294  FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2295 
2296  if (!This->child.reole)
2297  return CO_E_RELEASED;
2298 
2299  return E_NOTIMPL;
2300 }
2301 
2303  LONG *delta)
2304 {
2306 
2307  FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2308 
2309  if (!This->child.reole)
2310  return CO_E_RELEASED;
2311 
2312  return E_NOTIMPL;
2313 }
2314 
2316  LONG *delta)
2317 {
2319 
2320  FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2321 
2322  if (!This->child.reole)
2323  return CO_E_RELEASED;
2324 
2325  return E_NOTIMPL;
2326 }
2327 
2329  LONG *delta)
2330 {
2332 
2333  FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta);
2334 
2335  if (!This->child.reole)
2336  return CO_E_RELEASED;
2337 
2338  return E_NOTIMPL;
2339 }
2340 
2342  LONG *length)
2343 {
2345 
2346  FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
2347 
2348  if (!This->child.reole)
2349  return CO_E_RELEASED;
2350 
2351  return E_NOTIMPL;
2352 }
2353 
2355  LONG flags, LONG *length)
2356 {
2358 
2359  FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
2360 
2361  if (!This->child.reole)
2362  return CO_E_RELEASED;
2363 
2364  return E_NOTIMPL;
2365 }
2366 
2368  LONG flags, LONG *length)
2369 {
2371 
2372  FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length);
2373 
2374  if (!This->child.reole)
2375  return CO_E_RELEASED;
2376 
2377  return E_NOTIMPL;
2378 }
2379 
2381 {
2383 
2384  FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta);
2385 
2386  if (!This->child.reole)
2387  return CO_E_RELEASED;
2388 
2389  return E_NOTIMPL;
2390 }
2391 
2393 {
2395 
2396  FIXME("(%p)->(%p): stub\n", This, v);
2397 
2398  if (!This->child.reole)
2399  return CO_E_RELEASED;
2400 
2401  return E_NOTIMPL;
2402 }
2403 
2405 {
2407 
2408  FIXME("(%p)->(%p): stub\n", This, v);
2409 
2410  if (!This->child.reole)
2411  return CO_E_RELEASED;
2412 
2413  return E_NOTIMPL;
2414 }
2415 
2417 {
2419 
2420  FIXME("(%p)->(%s %x): stub\n", This, debugstr_variant(v), format);
2421 
2422  if (!This->child.reole)
2423  return CO_E_RELEASED;
2424 
2425  return E_NOTIMPL;
2426 }
2427 
2429 {
2431 
2432  FIXME("(%p)->(%s %x %p): stub\n", This, debugstr_variant(v), format, ret);
2433 
2434  if (!This->child.reole)
2435  return CO_E_RELEASED;
2436 
2437  return E_NOTIMPL;
2438 }
2439 
2441 {
2443 
2444  FIXME("(%p)->(%p): stub\n", This, ret);
2445 
2446  if (!This->child.reole)
2447  return CO_E_RELEASED;
2448 
2449  return E_NOTIMPL;
2450 }
2451 
2453 {
2455 
2456  FIXME("(%p)->(%d): stub\n", This, type);
2457 
2458  if (!This->child.reole)
2459  return CO_E_RELEASED;
2460 
2461  return E_NOTIMPL;
2462 }
2463 
2465 {
2467 
2468  FIXME("(%p)->(%d %p %p): stub\n", This, type, cx, cy);
2469 
2470  if (!This->child.reole)
2471  return CO_E_RELEASED;
2472 
2473  return E_NOTIMPL;
2474 }
2475 
2477  LONG extend)
2478 {
2480 
2481  FIXME("(%p)->(%d %d %d %d): stub\n", This, x, y, type, extend);
2482 
2483  if (!This->child.reole)
2484  return CO_E_RELEASED;
2485 
2486  return E_NOTIMPL;
2487 }
2488 
2490 {
2492  ME_TextEditor *editor;
2493  ME_Cursor cursor;
2494  int x, y, height;
2495 
2496  TRACE("(%p)->(%d)\n", This, value);
2497 
2498  if (!This->child.reole)
2499  return CO_E_RELEASED;
2500 
2501  editor = This->child.reole->editor;
2502 
2503  switch (value)
2504  {
2505  case tomStart:
2506  ME_CursorFromCharOfs(editor, This->start, &cursor);
2507  ME_GetCursorCoordinates(editor, &cursor, &x, &y, &height);
2508  break;
2509  default:
2510  FIXME("bStart value %d not handled\n", value);
2511  return E_NOTIMPL;
2512  }
2513  ME_ScrollAbs(editor, x, y);
2514  return S_OK;
2515 }
2516 
2518 {
2520 
2521  FIXME("(%p)->(%p): stub\n", This, ppv);
2522 
2523  if (!This->child.reole)
2524  return CO_E_RELEASED;
2525 
2526  return E_NOTIMPL;
2527 }
2528 
2529 static const ITextRangeVtbl trvt = {
2588 };
2589 
2590 /* ITextFont */
2592 {
2594 
2595  TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
2596 
2597  if (IsEqualIID(riid, &IID_ITextFont) ||
2600  {
2601  *ppv = iface;
2602  ITextFont_AddRef(iface);
2603  return S_OK;
2604  }
2605 
2606  *ppv = NULL;
2607  return E_NOINTERFACE;
2608 }
2609 
2611 {
2614  TRACE("(%p)->(%u)\n", This, ref);
2615  return ref;
2616 }
2617 
2619 {
2622 
2623  TRACE("(%p)->(%u)\n", This, ref);
2624 
2625  if (!ref)
2626  {
2627  if (This->range)
2628  ITextRange_Release(This->range);
2629  SysFreeString(This->props[FONT_NAME].str);
2630  heap_free(This);
2631  }
2632 
2633  return ref;
2634 }
2635 
2637 {
2639  TRACE("(%p)->(%p)\n", This, pctinfo);
2640  *pctinfo = 1;
2641  return S_OK;
2642 }
2643 
2645  ITypeInfo **ppTInfo)
2646 {
2648  HRESULT hr;
2649 
2650  TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
2651 
2652  hr = get_typeinfo(ITextFont_tid, ppTInfo);
2653  if (SUCCEEDED(hr))
2654  ITypeInfo_AddRef(*ppTInfo);
2655  return hr;
2656 }
2657 
2659  LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
2660 {
2662  ITypeInfo *ti;
2663  HRESULT hr;
2664 
2665  TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid),
2666  rgszNames, cNames, lcid, rgDispId);
2667 
2668  hr = get_typeinfo(ITextFont_tid, &ti);
2669  if (SUCCEEDED(hr))
2670  hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
2671  return hr;
2672 }
2673 
2675  ITextFont *iface,
2676  DISPID dispIdMember,
2677  REFIID riid,
2678  LCID lcid,
2679  WORD wFlags,
2680  DISPPARAMS *pDispParams,
2681  VARIANT *pVarResult,
2682  EXCEPINFO *pExcepInfo,
2683  UINT *puArgErr)
2684 {
2686  ITypeInfo *ti;
2687  HRESULT hr;
2688 
2689  TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid),
2690  lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2691 
2692  hr = get_typeinfo(ITextFont_tid, &ti);
2693  if (SUCCEEDED(hr))
2694  hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2695  return hr;
2696 }
2697 
2699 {
2701 
2702  TRACE("(%p)->(%p)\n", This, ret);
2703 
2704  if (!ret)
2705  return E_INVALIDARG;
2706 
2707  *ret = NULL;
2708  if (This->range && !get_range_reole(This->range))
2709  return CO_E_RELEASED;
2710 
2711  return create_textfont(NULL, This, ret);
2712 }
2713 
2715 {
2717  FIXME("(%p)->(%p): stub\n", This, pFont);
2718 
2719  if (This->range && !get_range_reole(This->range))
2720  return CO_E_RELEASED;
2721 
2722  return E_NOTIMPL;
2723 }
2724 
2726 {
2728  FIXME("(%p)->(%p): stub\n", This, ret);
2729 
2730  if (This->range && !get_range_reole(This->range))
2731  return CO_E_RELEASED;
2732 
2733  return E_NOTIMPL;
2734 }
2735 
2737 {
2739  FIXME("(%p)->(%p %p): stub\n", This, font, ret);
2740 
2741  if (This->range && !get_range_reole(This->range))
2742  return CO_E_RELEASED;
2743 
2744  return E_NOTIMPL;
2745 }
2746 
2748 {
2749  enum textfont_prop_id id;
2750 
2751  for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) {
2752  switch (id)
2753  {
2754  case FONT_ALLCAPS:
2755  case FONT_ANIMATION:
2756  case FONT_BOLD:
2757  case FONT_EMBOSS:
2758  case FONT_HIDDEN:
2759  case FONT_ENGRAVE:
2760  case FONT_ITALIC:
2761  case FONT_OUTLINE:
2762  case FONT_PROTECTED:
2763  case FONT_SHADOW:
2764  case FONT_SMALLCAPS:
2765  case FONT_STRIKETHROUGH:
2766  case FONT_SUBSCRIPT:
2767  case FONT_SUPERSCRIPT:
2768  case FONT_UNDERLINE:
2769  font->props[id].l = tomFalse;
2770  break;
2771  case FONT_BACKCOLOR:
2772  case FONT_FORECOLOR:
2773  font->props[id].l = tomAutoColor;
2774  break;
2775  case FONT_KERNING:
2776  case FONT_POSITION:
2777  case FONT_SIZE:
2778  case FONT_SPACING:
2779  font->props[id].f = 0.0;
2780  break;
2781  case FONT_LANGID:
2782  font->props[id].l = GetSystemDefaultLCID();
2783  break;
2784  case FONT_NAME: {
2785  static const WCHAR sysW[] = {'S','y','s','t','e','m',0};
2786  SysFreeString(font->props[id].str);
2787  font->props[id].str = SysAllocString(sysW);
2788  break;
2789  }
2790  case FONT_WEIGHT:
2791  font->props[id].l = FW_NORMAL;
2792  break;
2793  default:
2794  FIXME("font property %d not handled\n", id);
2795  }
2796  }
2797 }
2798 
2800 {
2801  enum textfont_prop_id id;
2802 
2803  for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) {
2804  switch (id)
2805  {
2806  case FONT_ALLCAPS:
2807  case FONT_ANIMATION:
2808  case FONT_BOLD:
2809  case FONT_EMBOSS:
2810  case FONT_HIDDEN:
2811  case FONT_ENGRAVE:
2812  case FONT_ITALIC:
2813  case FONT_OUTLINE:
2814  case FONT_PROTECTED:
2815  case FONT_SHADOW:
2816  case FONT_SMALLCAPS:
2817  case FONT_STRIKETHROUGH:
2818  case FONT_SUBSCRIPT:
2819  case FONT_SUPERSCRIPT:
2820  case FONT_UNDERLINE:
2821  case FONT_BACKCOLOR:
2822  case FONT_FORECOLOR:
2823  case FONT_LANGID:
2824  case FONT_WEIGHT:
2825  font->props[id].l = tomUndefined;
2826  break;
2827  case FONT_KERNING:
2828  case FONT_POSITION:
2829  case FONT_SIZE:
2830  case FONT_SPACING:
2831  font->props[id].f = tomUndefined;
2832  break;
2833  case FONT_NAME:
2834  break;
2835  default:
2836  FIXME("font property %d not handled\n", id);
2837  }
2838  }
2839 }
2840 
2842 {
2843  enum textfont_prop_id propid;
2844  for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++)
2845  set_textfont_prop(font, propid, &font->props[propid]);
2846 }
2847 
2849 {
2851 
2852  TRACE("(%p)->(%d)\n", This, value);
2853 
2854  /* If font is attached to a range, released or not, we can't
2855  reset to undefined */
2856  if (This->range) {
2857  if (!get_range_reole(This->range))
2858  return CO_E_RELEASED;
2859 
2860  switch (value)
2861  {
2862  case tomUndefined:
2863  return E_INVALIDARG;
2864  case tomCacheParms:
2866  This->get_cache_enabled = TRUE;
2867  break;
2868  case tomTrackParms:
2869  This->get_cache_enabled = FALSE;
2870  break;
2871  case tomApplyLater:
2872  This->set_cache_enabled = TRUE;
2873  break;
2874  case tomApplyNow:
2875  This->set_cache_enabled = FALSE;
2877  break;
2878  case tomUsePoints:
2879  case tomUseTwips:
2880  return E_INVALIDARG;
2881  default:
2882  FIXME("reset mode %d not supported\n", value);
2883  }
2884 
2885  return S_OK;
2886  }
2887  else {
2888  switch (value)
2889  {
2890  /* reset to global defaults */
2891  case tomDefault:
2893  return S_OK;
2894  /* all properties are set to tomUndefined, font name is retained */
2895  case tomUndefined:
2897  return S_OK;
2898  case tomApplyNow:
2899  case tomApplyLater:
2900  case tomTrackParms:
2901  case tomCacheParms:
2902  return S_OK;
2903  case tomUsePoints:
2904  case tomUseTwips:
2905  return E_INVALIDARG;
2906  }
2907  }
2908 
2909  FIXME("reset mode %d not supported\n", value);
2910  return E_NOTIMPL;
2911 }
2912 
2914 {
2916  FIXME("(%p)->(%p): stub\n", This, value);
2917 
2918  if (This->range && !get_range_reole(This->range))
2919  return CO_E_RELEASED;
2920 
2921  return E_NOTIMPL;
2922 }
2923 
2925 {
2927  FIXME("(%p)->(%d): stub\n", This, value);
2928 
2929  if (This->range && !get_range_reole(This->range))
2930  return CO_E_RELEASED;
2931 
2932  return E_NOTIMPL;
2933 }
2934 
2936 {
2938  TRACE("(%p)->(%p)\n", This, value);
2940 }
2941 
2943 {
2945  TRACE("(%p)->(%d)\n", This, value);
2947 }
2948 
2950 {
2952  TRACE("(%p)->(%p)\n", This, value);
2954 }
2955 
2957 {
2959 
2960  TRACE("(%p)->(%d)\n", This, value);
2961 
2963  return E_INVALIDARG;
2964 
2966 }
2967 
2969 {
2971  TRACE("(%p)->(%p)\n", This, value);
2973 }
2974 
2976 {
2978  TRACE("(%p)->(%d)\n", This, value);
2980 }
2981 
2983 {
2985  TRACE("(%p)->(%p)\n", This, value);
2987 }
2988 
2990 {
2992  TRACE("(%p)->(%d)\n", This, value);
2994 }
2995 
2997 {
2999  TRACE("(%p)->(%p)\n", This, value);
3001 }
3002 
3004 {
3006  TRACE("(%p)->(%d)\n", This, value);
3008 }
3009 
3011 {
3013  TRACE("(%p)->(%p)\n", This, value);
3015 }
3016 
3018 {
3020  TRACE("(%p)->(%d)\n", This, value);
3022 }
3023 
3025 {
3027  TRACE("(%p)->(%p)\n", This, value);
3029 }
3030 
3032 {
3034  TRACE("(%p)->(%d)\n", This, value);
3036 }
3037 
3039 {
3041  TRACE("(%p)->(%p)\n", This, value);
3043 }
3044 
3046 {
3048  TRACE("(%p)->(%d)\n", This, value);
3050 }
3051 
3053 {
3055  TRACE("(%p)->(%p)\n", This, value);
3057 }
3058 
3060 {
3062  TRACE("(%p)->(%d)\n", This, value);
3064 }
3065 
3067 {
3069  TRACE("(%p)->(%p)\n", This, value);
3071 }
3072 
3074 {
3076  TRACE("(%p)->(%.2f)\n", This, value);
3078 }
3079 
3081 {
3083  TRACE("(%p)->(%p)\n", This, value);
3085 }
3086 
3088 {
3090  TRACE("(%p)->(%d)\n", This, value);
3092 }
3093 
3095 {
3097 
3098  TRACE("(%p)->(%p)\n", This, value);
3099 
3100  if (!value)
3101  return E_INVALIDARG;
3102 
3103  *value = NULL;
3104 
3105  if (!This->range) {
3106  if (This->props[FONT_NAME].str)
3107  *value = SysAllocString(This->props[FONT_NAME].str);
3108  else
3109  *value = SysAllocStringLen(NULL, 0);
3110  return *value ? S_OK : E_OUTOFMEMORY;
3111  }
3112 
3113  return textfont_getname_from_range(This->range, value);
3114 }
3115 
3117 {
3120 
3121  TRACE("(%p)->(%s)\n", This, debugstr_w(value));
3122 
3123  v.str = value;
3124  return set_textfont_prop(This, FONT_NAME, &v);
3125 }
3126 
3128 {
3130  TRACE("(%p)->(%p)\n", This, value);
3132 }
3133 
3135 {
3137  TRACE("(%p)->(%d)\n", This, value);
3139 }
3140 
3142 {
3144  TRACE("(%p)->(%p)\n", This, value);
3146 }
3147 
3149 {
3151  TRACE("(%p)->(%.2f)\n", This, value);
3153 }
3154 
3156 {
3158  TRACE("(%p)->(%p)\n", This, value);
3160 }
3161 
3163 {
3165  TRACE("(%p)->(%d)\n", This, value);
3167 }
3168 
3170 {
3172  TRACE("(%p)->(%p)\n", This, value);
3174 }
3175 
3177 {
3179  TRACE("(%p)->(%d)\n", This, value);
3181 }
3182 
3184 {
3186  TRACE("(%p)->(%p)\n", This, value);
3188 }
3189 
3191 {
3193  TRACE("(%p)->(%.2f)\n", This, value);
3195 }
3196 
3198 {
3200  TRACE("(%p)->(%p)\n", This, value);
3202 }
3203 
3205 {
3207  TRACE("(%p)->(%d)\n", This, value);
3209 }
3210 
3212 {
3214  TRACE("(%p)->(%p)\n", This, value);
3216 }
3217 
3219 {
3221  TRACE("(%p)->(%.2f)\n", This, value);
3223 }
3224 
3226 {
3228  TRACE("(%p)->(%p)\n", This, value);
3230 }
3231 
3233 {
3235  TRACE("(%p)->(%d)\n", This, value);
3237 }
3238 
3240 {
3242  TRACE("(%p)->(%p)\n", This, value);
3244 }
3245 
3247 {
3249  TRACE("(%p)->(%d)\n", This, value);
3251 }
3252 
3254 {
3256  TRACE("(%p)->(%p)\n", This, value);
3258 }
3259 
3261 {
3263  TRACE("(%p)->(%d)\n", This, value);
3265 }
3266 
3268 {
3270  TRACE("(%p)->(%p)\n", This, value);
3272 }
3273 
3275 {
3277  TRACE("(%p)->(%d)\n", This, value);
3279 }
3280 
3282 {
3284  TRACE("(%p)->(%p)\n", This, value);
3286 }
3287 
3289 {
3291  TRACE("(%p)->(%d)\n", This, value);
3293 }
3294 
3295 static ITextFontVtbl textfontvtbl = {
3358 };
3359 
3361 {
3363 
3364  *ret = NULL;
3365  font = heap_alloc(sizeof(*font));
3366  if (!font)
3367  return E_OUTOFMEMORY;
3368 
3369  font->ITextFont_iface.lpVtbl = &textfontvtbl;
3370  font->ref = 1;
3371 
3372  if (src) {
3373  font->range = NULL;
3374  font->get_cache_enabled = TRUE;
3375  font->set_cache_enabled = TRUE;
3376  memcpy(&font->props, &src->props, sizeof(font->props));
3377  if (font->props[FONT_NAME].str)
3378  font->props[FONT_NAME].str = SysAllocString(font->props[FONT_NAME].str);
3379  }
3380  else {
3381  font->range = range;
3382  ITextRange_AddRef(range);
3383 
3384  /* cache current properties */
3385  font->get_cache_enabled = FALSE;
3386  font->set_cache_enabled = FALSE;
3388  }
3389 
3390  *ret = &font->ITextFont_iface;
3391  return S_OK;
3392 }
3393 
3394 /* ITextPara */
3396 {
3398 
3399  TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
3400 
3401  if (IsEqualIID(riid, &IID_ITextPara) ||
3404  {
3405  *ppv = iface;
3406  ITextPara_AddRef(iface);
3407  return S_OK;
3408  }
3409 
3410  *ppv = NULL;
3411  return E_NOINTERFACE;
3412 }
3413 
3415 {
3418  TRACE("(%p)->(%u)\n", This, ref);
3419  return ref;
3420 }
3421 
3423 {
3426 
3427  TRACE("(%p)->(%u)\n", This, ref);
3428 
3429  if (!ref)
3430  {
3431  ITextRange_Release(This->range);
3432  heap_free(This);
3433  }
3434 
3435  return ref;
3436 }
3437 
3439 {
3440  if (This->range)
3441  {
3442  ITextRangeImpl *rng = impl_from_ITextRange(This->range);
3443  return rng->child.reole;
3444  }
3445  return NULL;
3446 }
3447 
3449 {
3451  TRACE("(%p)->(%p)\n", This, pctinfo);
3452  *pctinfo = 1;
3453  return S_OK;
3454 }
3455 
3457  ITypeInfo **ppTInfo)
3458 {
3460  HRESULT hr;
3461 
3462  TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo);
3463 
3464  hr = get_typeinfo(ITextPara_tid, ppTInfo);
3465  if (SUCCEEDED(hr))
3466  ITypeInfo_AddRef(*ppTInfo);
3467  return hr;
3468 }
3469 
3471  LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
3472 {
3474  ITypeInfo *ti;
3475  HRESULT hr;
3476 
3477  TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames,
3478  cNames, lcid, rgDispId);
3479 
3480  hr = get_typeinfo(ITextPara_tid, &ti);
3481  if (SUCCEEDED(hr))
3482  hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId);
3483  return hr;
3484 }
3485 
3487  ITextPara *iface,
3488  DISPID dispIdMember,
3489  REFIID riid,
3490  LCID lcid,
3491  WORD wFlags,
3492  DISPPARAMS *pDispParams,
3493  VARIANT *pVarResult,
3494  EXCEPINFO *pExcepInfo,
3495  UINT *puArgErr)
3496 {
3498  ITypeInfo *ti;
3499  HRESULT hr;
3500 
3501  TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember,
3502  debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult,
3503  pExcepInfo, puArgErr);
3504 
3505  hr = get_typeinfo(ITextPara_tid, &ti);
3506  if (SUCCEEDED(hr))
3507  hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
3508  return hr;
3509 }
3510 
3512 {
3514  FIXME("(%p)->(%p)\n", This, ret);
3515 
3516  if (!para_get_reole(This))
3517  return CO_E_RELEASED;
3518 
3519  return E_NOTIMPL;
3520 }
3521 
3523 {
3525  FIXME("(%p)->(%p)\n", This, para);
3526 
3527  if (!para_get_reole(This))
3528  return CO_E_RELEASED;
3529 
3530  return E_NOTIMPL;
3531 }
3532 
3534 {
3536  FIXME("(%p)->(%p)\n", This, ret);
3537 
3538  if (!para_get_reole(This))
3539  return CO_E_RELEASED;
3540 
3541  return E_NOTIMPL;
3542 }
3543 
3545 {
3547  FIXME("(%p)->(%p %p)\n", This, para, ret);
3548 
3549  if (!para_get_reole(This))
3550  return CO_E_RELEASED;
3551 
3552  return E_NOTIMPL;
3553 }
3554 
3556 {
3558  FIXME("(%p)->(%d)\n", This, value);
3559 
3560  if (!para_get_reole(This))
3561  return CO_E_RELEASED;
3562 
3563  return E_NOTIMPL;
3564 }
3565 
3567 {
3569  FIXME("(%p)->(%p)\n", This, value);
3570 
3571  if (!para_get_reole(This))
3572  return CO_E_RELEASED;
3573 
3574  return E_NOTIMPL;
3575 }
3576 
3578 {
3580  FIXME("(%p)->(%d)\n", This, value);
3581 
3582  if (!para_get_reole(This))
3583  return CO_E_RELEASED;
3584 
3585  return E_NOTIMPL;
3586 }
3587 
3589 {
3591  static int once;
3592 
3593  if (!once++) FIXME("(%p)->(%p)\n", This, value);
3594 
3595  if (!para_get_reole(This))
3596  return CO_E_RELEASED;
3597 
3598  return E_NOTIMPL;
3599 }
3600 
3602 {
3604  FIXME("(%p)->(%d)\n", This, value);
3605 
3606  if (!para_get_reole(This))
3607  return CO_E_RELEASED;
3608 
3609  return E_NOTIMPL;
3610 }
3611 
3613 {
3615  FIXME("(%p)->(%p)\n", This, value);
3616 
3617  if (!para_get_reole(This))
3618  return CO_E_RELEASED;
3619 
3620  return E_NOTIMPL;
3621 }
3622 
3624 {
3626  FIXME("(%p)->(%d)\n", This, value);
3627 
3628  if (!para_get_reole(This))
3629  return CO_E_RELEASED;
3630 
3631  return E_NOTIMPL;
3632 }
3633 
3635 {
3637  FIXME("(%p)->(%p)\n", This, value);
3638 
3639  if (!para_get_reole(This))
3640  return CO_E_RELEASED;
3641 
3642  return E_NOTIMPL;
3643 }
3644 
3646 {
3648  FIXME("(%p)->(%p)\n", This, value);
3649 
3650  if (!para_get_reole(This))
3651  return CO_E_RELEASED;
3652 
3653  return E_NOTIMPL;
3654 }
3655 
3657 {
3659  FIXME("(%p)->(%d)\n", This, value);
3660 
3661  if (!para_get_reole(This))
3662  return CO_E_RELEASED;
3663 
3664  return E_NOTIMPL;
3665 }
3666 
3668 {
3670  FIXME("(%p)->(%p)\n", This, value);
3671 
3672  if (!para_get_reole(This))
3673  return CO_E_RELEASED;
3674 
3675  return E_NOTIMPL;
3676 }
3677 
3679 {
3681  FIXME("(%p)->(%d)\n", This, value);
3682 
3683  if (!para_get_reole(This))
3684  return CO_E_RELEASED;
3685 
3686  return E_NOTIMPL;
3687 }
3688 
3690 {
3692  FIXME("(%p)->(%p)\n", This, value);
3693 
3694  if (!para_get_reole(This))
3695  return CO_E_RELEASED;
3696 
3697  return E_NOTIMPL;
3698 }
3699 
3701 {
3703  FIXME("(%p)->(%p)\n", This, value);
3704 
3705  if (!para_get_reole(This))
3706  return CO_E_RELEASED;
3707 
3708  return E_NOTIMPL;
3709 }
3710 
3712 {
3714  FIXME("(%p)->(%p)\n", This, value);
3715 
3716  if (!para_get_reole(This))
3717  return CO_E_RELEASED;
3718 
3719  return E_NOTIMPL;
3720 }
3721 
3723 {
3725  FIXME("(%p)->(%p)\n", This, value);
3726 
3727  if (!para_get_reole(This))
3728  return CO_E_RELEASED;
3729 
3730  return E_NOTIMPL;
3731 }
3732 
3734 {
3736  FIXME("(%p)->(%d)\n", This, value);
3737 
3738  if (!para_get_reole(This))
3739  return CO_E_RELEASED;
3740 
3741  return E_NOTIMPL;
3742 }
3743 
3745 {
3747  FIXME("(%p)->(%p)\n", This, value);
3748 
3749  if (!para_get_reole(This))
3750  return CO_E_RELEASED;
3751 
3752  return E_NOTIMPL;
3753 }
3754 
3756 {
3758  FIXME("(%p)->(%d)\n", This, value);
3759 
3760  if (!para_get_reole(This))
3761  return CO_E_RELEASED;
3762 
3763  return E_NOTIMPL;
3764 }
3765 
3767 {
3769  FIXME("(%p)->(%p)\n", This, value);
3770 
3771  if (!para_get_reole(This))
3772  return CO_E_RELEASED;
3773 
3774  return E_NOTIMPL;
3775 }
3776 
3778 {
3780  FIXME("(%p)->(%d)\n", This, value);
3781 
3782  if (!para_get_reole(This))
3783  return CO_E_RELEASED;
3784 
3785  return E_NOTIMPL;
3786 }
3787 
3789 {
3791  FIXME("(%p)->(%p)\n", This, value);
3792 
3793  if (!para_get_reole(This))
3794  return CO_E_RELEASED;
3795 
3796  return E_NOTIMPL;
3797 }
3798 
3800 {
3802  FIXME("(%p)->(%.2f)\n", This, value);
3803 
3804  if (!para_get_reole(This))
3805  return CO_E_RELEASED;
3806 
3807  return E_NOTIMPL;
3808 }
3809 
3811 {
3813  FIXME("(%p)->(%p)\n", This, value);
3814 
3815  if (!para_get_reole(This))
3816  return CO_E_RELEASED;
3817 
3818  return E_NOTIMPL;
3819 }
3820 
3822 {
3824  FIXME("(%p)->(%d)\n", This, value);
3825 
3826  if (!para_get_reole(This))
3827  return CO_E_RELEASED;
3828 
3829  return E_NOTIMPL;
3830 }
3831 
3833 {
3835  FIXME("(%p)->(%p)\n", This, value);
3836 
3837  if (!para_get_reole(This))
3838  return CO_E_RELEASED;
3839 
3840  return E_NOTIMPL;
3841 }
3842 
3844 {
3846  FIXME("(%p)->(%d)\n", This, value);
3847 
3848  if (!para_get_reole(This))
3849  return CO_E_RELEASED;
3850 
3851  return E_NOTIMPL;
3852 }
3853 
3855 {
3857  FIXME("(%p)->(%p)\n", This, value);
3858 
3859  if (!para_get_reole(This))
3860  return CO_E_RELEASED;
3861 
3862  return E_NOTIMPL;
3863 }
3864 
3866 {
3868  FIXME("(%p)->(%d)\n", This, value);
3869 
3870  if (!para_get_reole(This))
3871  return CO_E_RELEASED;
3872 
3873  return E_NOTIMPL;
3874 }
3875 
3877 {
3879  FIXME("(%p)->(%p)\n", This, value);
3880 
3881  if (!para_get_reole(This))
3882  return CO_E_RELEASED;
3883 
3884  return E_NOTIMPL;
3885 }
3886 
3888 {
3890  FIXME("(%p)->(%.2f)\n", This, value);
3891 
3892  if (!para_get_reole(This))
3893  return CO_E_RELEASED;
3894 
3895  return E_NOTIMPL;
3896 }
3897 
3898 static HRESULT WINAPI TextPara_SetIndents(ITextPara *iface, FLOAT StartIndent, FLOAT LeftIndent, FLOAT RightIndent)
3899 {
3901  FIXME("(%p)->(%.2f %.2f %.2f)\n", This, StartIndent, LeftIndent, RightIndent);
3902 
3903  if (!para_get_reole(This))
3904  return CO_E_RELEASED;
3905 
3906  return E_NOTIMPL;
3907 }
3908 
3909 static HRESULT WINAPI TextPara_SetLineSpacing(ITextPara *iface, LONG LineSpacingRule, FLOAT LineSpacing)
3910 {
3912  FIXME("(%p)->(%d %.2f)\n", This, LineSpacingRule, LineSpacing);
3913 
3914  if (!para_get_reole(This))
3915  return CO_E_RELEASED;
3916 
3917  return E_NOTIMPL;
3918 }
3919 
3921 {
3923  FIXME("(%p)->(%p)\n", This, value);
3924 
3925  if (!para_get_reole(This))
3926  return CO_E_RELEASED;
3927 
3928  return E_NOTIMPL;
3929 }
3930 
3932 {
3934  FIXME("(%p)->(%.2f)\n", This, value);
3935 
3936  if (!para_get_reole(This))
3937  return CO_E_RELEASED;
3938 
3939  return E_NOTIMPL;
3940 }
3941 
3943 {
3945  FIXME("(%p)->(%p)\n", This, value);
3946 
3947  if (!para_get_reole(This))
3948  return CO_E_RELEASED;
3949 
3950  return E_NOTIMPL;
3951 }
3952 
3954 {
3956  FIXME("(%p)->(%.2f)\n", This, value);
3957 
3958  if (!para_get_reole(This))
3959  return CO_E_RELEASED;
3960 
3961  return E_NOTIMPL;
3962 }
3963 
3965 {
3967  FIXME("(%p)->(%p)\n", This, value);
3968 
3969  if (!para_get_reole(This))
3970  return CO_E_RELEASED;
3971 
3972  return E_NOTIMPL;
3973 }
3974 
3976 {
3978  FIXME("(%p)->(%d)\n", This, value);
3979 
3980  if (!para_get_reole(This))
3981  return CO_E_RELEASED;
3982 
3983  return E_NOTIMPL;
3984 }
3985 
3987 {
3989  FIXME("(%p)->(%p)\n", This, value);
3990 
3991  if (!para_get_reole(This))
3992  return CO_E_RELEASED;
3993 
3994  return E_NOTIMPL;
3995 }
3996 
3997 static HRESULT WINAPI TextPara_AddTab(ITextPara *iface, FLOAT tbPos, LONG tbAlign, LONG tbLeader)
3998 {
4000  FIXME("(%p)->(%.2f %d %d)\n", This, tbPos, tbAlign, tbLeader);
4001 
4002  if (!para_get_reole(This))
4003  return CO_E_RELEASED;
4004 
4005  return E_NOTIMPL;
4006 }
4007 
4009 {
4011  FIXME("(%p)\n", This);
4012 
4013  if (!para_get_reole(This))
4014  return CO_E_RELEASED;
4015 
4016  return E_NOTIMPL;
4017 }
4018 
4020 {
4022  FIXME("(%p)->(%.2f)\n", This, pos);
4023 
4024  if (!para_get_reole(This))
4025  return CO_E_RELEASED;
4026 
4027  return E_NOTIMPL;
4028 }
4029 
4030 static HRESULT WINAPI <